ImageVerifierCode 换一换
格式:DOCX , 页数:29 ,大小:488.02KB ,
资源ID:2212943      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bingdoc.com/d-2212943.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(第九章 编程实例.docx)为本站会员(b****2)主动上传,冰点文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰点文库(发送邮件至service@bingdoc.com或直接QQ联系客服),我们立即给予删除!

第九章 编程实例.docx

1、第九章 编程实例第九章 C语言编程应用 一、数据采集的C语言编程例1 ADC0809与8052接口的数据采集程序举例。# include # include # define uchar unsigned char # define IN0 XBYTE 0x7ff8 / 设AD0809通道0地址 ,未用置1sbit ad_busy =P33 ; / 即EOC状态 void ad0809 ( uchar idata *x ) / A/D采集函数,采样结果放数组x中 uchar i ; uchar *ad_adr ; ad_adr= & IN0 ;/将通道0地址送入指针 for ( i=0 ; i

2、8 ;i+ ) / 处理8通道 *ad_adr=0 ; / 用写信号启动转换 for(i=0;i3;i+); /查询前延时10s while (ad_busy = =0 ) ; / 查询P3.3等待转换结束 xi = * ad_adr ; / 存转换结果, ad_adr + ; / 下一通道 void main ( void ) static uchar idata ad 8 ;/设置静态数组 ad0809 ( ad ) ; / 采样AD0809通道的值,ad为数组首地址 以上是采用查询法,也可以用中断法控制采样。采用中断时,EOC信号要经非门接外部中断信号。用外部中断0低电平中断。程序地址与

3、上面的电路不同,0通道地址为0x8000,其它控制是相同的。#include#include /XBYTE函数#include/_nop_函数#define uchar unsigned char #define uint unsigned int#define DAADR XBYTE0x8000 /ad0809的0通道地址uchar dd8,m=0; /转换结果在dd8中uchar *ad_adr;/全局变量void main(void) uchar i=0; ad_adr=&DAADR;/给指针赋初值 DAADR=0x00;/采样IN0通道,并启动采样 for(i=0;i3;i+);/避开

4、EOC未变化的10s IE=0x81;/开中断 while(1) / disp1(0);在此可以显示,处理数据 void ad0809int(void) interrupt 0 using 1 /中断程序 IE=0X00;/关中断 ddm=*ad_adr;/ 存贮转换结果 ad_adr+;/指向下一个通道 ad_adr=0;/开始下一次转换 m+;/指向下一个数组元素 _nop_();/根据晶振频率调整时间 if(m=8) m=0; ad_adr=&DAADR; IE=0X81;/开中断 (0809采样)例2 I2C总线A/D转换(TLC0831)TLC0831是8位逐次逼近电压型I2C总线A

5、/D转换器,支持单信道输入串口输出,极性设置固定,不需寻址。其内部有一采样数据比较器将输入的摸拟信号微分比较后转换为数字信号。模拟电压的差分输入方式有利于抑制共模信号和减少或消除转换的偏移误差。电压基准输入可调,使得小范围模拟电压信号转化时的分辨率更高。由标准移位寄存器或微处理器将时间变化的数字信号分配到串口输出,当IN-接地时为单端工作,此时IN+为输入,也可将信号差分后输入到IN+与IN-之间,此时器件处于双端工作状态。主要特点如下:(1) 8位分辨率;(2) 单信道差分输入;(3) 5V的电源提供0-5V可调基准电压;(4) 输入输出可与TTL和MOS兼容;(5) 总失调误差为1SB。(

6、6)串行时钟在250KHz时,转换时间为32s。典型的应用电路如下图:TLC0831共8个引脚, CS:为片选,低电平有效,并启动转换,在转换过程中必须保持低电平;DO:为数据输出端;CLK:时钟信号。IN:模拟信号输入正极;IN:模拟信号输入负极。 在转换过程中,转换数据同时从DO口输出。TLC0831时序图如下: 按照时序图和电路图,可以编写出如下的应用程序,调用该程序一次可以完成一次转换,并将转换结果读入单片机A中:编写的C51应用程序: #include #include typedef unsigned int uuint;typedef unsigned char uchar;sb

7、it adcdo=P1_0; /定义TLC0831的数据线D0sbit adccs=P1_2; /定义TLC0831的时能线CSsbit adcclk=P1_1; /定义TLC0831的时钟线CLKvoid delay(uchar x); /定义廷时函数uchar readadc(void); /定义读数据函数void adcck(void); /定义时钟函数void delay1(uchar x)uchar i;for(i=0;ix;i+);void adcck(void) /时钟函数adcclk=1;delay1(2);adcclk=0;delay1(2);uchar readadc(vo

8、id) /读出TLC0831转换数据函数 uchar i;uchar ch;adccs=0;adcck();ch=0;for(;adcdo=1;)adcck();for(i=0;i8;i+) adcck();ch=(ch1)|adcdo;adccs=1;return(ch); /返回值,即转换后的数据void main(void) /主函数 uchar a;a=readadc();ACC=a;二、 AT24C系列串行E2PROM 特点:AT24CXX系列串行E2PROM是具有I2C总线接口功能的电可擦除串行EEPROM器件,具有掉电保护功能,功耗小,宽电源电压(25V-60V)的特点。在智能仪

9、器中,对于断电后需要保存的数据和可以在线修改的参数,采用该存储器是很方便的。常用器件:常用的有AT24C02(256字节),AT24C04(512字节),AT24C08(1 024字节),AT24c16(2 048字节)等。地址确定:AT24c系列串行E2PROM器件寻址字节中的最高4位(D7D4)为1010;器件地址中的低3位为引脚地址A2,A1,A0,对应器件寻址字节中的D3,D2,D1位,应用方法如下:1) 容量小于256字节的芯片(AT24C0102),由引脚地址A2,A1,A0,组合可以扩展8片;2) 对于AT24C04(512字节),A0引脚不可用,由输入器件地址时编程为0或1;由

10、A1、A2确定还可以扩展4片;3) 对于AT24C08(1024字节),A0、A1引脚不可用,由输入器件地址时编程为0或1;由A2确定还可以扩展2片;4) 对于AT24C16(2048字节),A0 、A1、A2引脚均不可用,由输入器件地址时编程为0或1; 5) 对于AT24C32以上的芯片,存储单元地址需要输入高位和低位两个字节,最大寻址能力为64K。页面寻址:以256字节为1页,则多于8位的寻址视为页面寻址。在AT24C系列中,对页面寻址位采取占用器件引脚地址(A2,Al,A0)的办法,凡在系统中引脚地址用做页地址后,该引脚在电路中不得使用,悬空处理。注意:数据写入时有“帧格式”和“页格式”

11、。“帧格式”是一次写入一个8位数数据;“页格式”是一次可以连续写入规定的数据个数,一般是8个数据。 注意区别“页格式”写入、读出与前面的页寻址的区别。详细的写入格式见见下图。写数据的时候,次序为:开始信号发器件地址发应答信号发数据地址发应答信号(数据传送)停止。 读的时候,次序为:开始信号发送器件地址发送应答信号发送数据地址发送应答信号又发开始信号发器件地址发应答信号(数据传送,同写入方式)停止。 对器件的读写操作比较复杂,在应用时要注意研究。 例3 AT89C52和AT24C02硬件连接和编程。 芯片中:TEST为写保护,接地时允许正常读写,接高电平保护数据。其余在前面均介绍过。 因A2、A

12、1、A0=000,故单片机读AT24C02时,器件地址SLAR=1,0100001B=0A1 H;写AT24C02时,器件地址SLAW=10100000B=0A0H。 由于AT89C51没有I2C接口,必须进行编程模拟。1) 用C语言编写的读、写程序编程技巧:(1) 必须弄懂I2C工作的基本原理(2) 严格按时序图和规定参考程序如下:#include #include /函数声明 ,次序安排好不用声明/void i2c_send8bit(unsigned char); /unsigned char i2c_receive8bit(void); sbit SDA=P10;/数据接口sbit SC

13、L=P11;/时钟脉冲接口/时钟脉冲为高电平时,数据从高变低,为开始信号 void i2c_start(void) SDA = 1; SCL = 1; SDA = 0; SCL = 0; return; /时钟脉冲为高电平时,数据从低变高,为结束信号 void i2c_stop(void) SDA = 0; SCL = 1; SDA = 1; return; /发送8位数据,数据保持稳定不变,SCL给一个脉冲 void i2c_send8bit(unsigned char b) unsigned char a; /数据移位控制变量for(a=0;a8;a+) if (b a ) & 0x80)

14、 /取最高位,先发送最高位SDA = 1; /最高位为1发送高电平else SDA = 0; /最高位为0发送低电平SCL = 1; SCL = 0; /产生时钟脉冲 return; /接收8位数据 ,时序同写,保持SCL为高电平,读SDAunsigned char i2c_receive8bit(void) unsigned char a; /读的位数unsigned char b=0; for(a=0;a8;a+) SCL = 1; /保持SCL为高电平b=b1; /读1位左移1次if (SDA=1) b=b|0x01; /按位或 ,从低位开始接收,移位8次到高位,先接收的是最高位SCL

15、= 0; /结束时钟脉冲 /当SDA为低电平时,SCL给一个高电平脉冲为接收确认信号 bit i2c_ack(void) bit ack; /应答成功信号,为“0”应答成功SDA = 1; /将SDA拉高,保证低电平由I2C总线接口产生SCL = 1; /时钟由低变高if (SDA=1) ack = 1; /应答不成功else ack = 0; /应答成功SCL = 0; /SDA为高电平,时钟由高变低,应答成功return (ack); /i2c_write(地址,数据),写一个字节 void i2c_write(unsigned char Address,unsigned char Dat

16、a) do i2c_start(); /启动信号i2c_send8bit(0xA0); /送器件地址(写)while(i2c_ack(); /应答成功则器件地址写成功i2c_send8bit(Address); /送8位地址i2c_ack(); /调应答i2c_send8bit(Data); /送8位数据i2c_ack();/调应答i2c_stop();/调停止return; /i2c_read(地址,数据),读一个字节 unsigned char i2c_read(unsigned char Address) unsigned char c; /存接收的数据do i2c_start(); /

17、开始i2c_send8bit(0xA0); /注意:送器件地址(写)while(i2c_ack(); /=1,表示无确认,再次发送 i2c_send8bit(Address); /送8位地址i2c_ack(); /应答do i2c_start(); /开始i2c_send8bit(0xA1); /注意:送器件地址(读)while(i2c_ack(); /应答c=i2c_receive8bit(); /读数据送变量Ci2c_ack(); /应答i2c_stop(); return(c); return (b); /= 主程序 = void main(void) unsigned char dd;

18、 for(;) /无限循环i2c_write(0x00,0x55); /给地址00写数据0x55_nop_(); dd=i2c_read(0x00); /从地址00开始读 2)下面是采用单片机C语言和汇编语言混合编写的程序#include #include /函数声明 extern void send8bit(unsigned char); extern unsigned char receive8bit(char);/注意说明格式 sbit SDA=P10;sbit SCL=P11;/发送开始信号 void i2c_start(void) SDA = 1; SCL = 1; SDA = 0;

19、 SCL = 0; return; /发送结束信号 void i2c_stop(void) SDA = 0; SCL = 1; SDA = 1; return; /发送接收确认信号 bit i2c_ack(void) bit ack; SDA = 1; SCL = 1; if (SDA=1) ack = 1; else ack = 0; SCL = 0; return (ack); /i2c_write(地址,数据),写一个字节 void i2c_write(unsigned char Address,unsigned char Data) do i2c_start(); send8bit(0

20、xA0); while(i2c_ack(); send8bit(Address); i2c_ack(); send8bit(Data); i2c_ack(); i2c_stop(); return; /i2c_read(地址,数据),读一个字节 unsigned char i2c_read(unsigned char Address) unsigned char c; do i2c_start(); send8bit(0xA0); while(i2c_ack(); /=1,表示无确认,再次发送 send8bit(Address); i2c_ack(); do i2c_start(); send

21、8bit(0xA1); while(i2c_ack(); c=receive8bit(0x00); /虽然无参数传递到汇编程序中,但必须给参数i2c_ack(); i2c_stop(); return(c); void main(void) unsigned char dd; for(;) i2c_write(0x00,0x55); _nop_(); dd=i2c_read(0x00); 下面是汇编语言程序,循环发送和接收8位数据。NAME SENDANDREC SDA EQU P1.0;定义端口 SCL EQU P1.1;送八位数据 PUBLIC _SEND8BITSENDBYTE SEGM

22、ENT CODERSEG SENDBYTE_SEND8BIT: MOV A,R7;取数据 MOV B,#08H SEND8BIT_A:RLC A MOV SDA,C SETB SCL NOP NOP CLR SCL DJNZ B,SEND8BIT_A RET ;接收八位数据PUBLIC _RECEIVE8BITRECEIVE8BIT SEGMENT CODERSEG RECEIVE8BIT_RECEIVE8BIT:MOV B,#08H CLR A SETB SDA RECEIVE8IT_A:SETB SCL NOP NOP MOV C,SDA RLC A CLR SCL DJNZ B,RECE

23、IVE8IT_A MOV R7,A;送结果 RET END三、 键盘和数码显示人机交互的C语言编程1、 行列式键盘与AT89C52的接口 键盘输入信息的主要过程是: (1) 单片机判断是否有键按下。 (2) 确定按下的是哪一个键。 (3) 把此步骤代表的信息翻译成计算机所能识别的代码,如ASCII或其它特征码。例4 44键盘的扫描程序。扫描程序查询的内容为: (1) 查询是否有键按下。首先单片机向行扫描P1.0 P1.3输出全为0扫描码F0H,然后从列检查口P1.4 P1.7输入列扫描信号,只要有一列信号不为1,即P1口不为F0H,则表示有键按下。接着要查出按下键所在的行、列位置。(2) 查询

24、按下键所在的行列位置。单片机将得到的信号取反,P1.4P1.7中的为1的位便是键所在的列。接下来要确定键所在的行,需要进行逐行扫描。单片机首先使P1.0为0,P1.1P1.7为1,即向P1口发送扫描码FEH,接着输入列检查信号,若全为1,表示不在第一行。接着使P1.1接地,其余为1,再读入列信号这样逐行发0扫描码,直到找到按下键所在的行,将该行扫描码取反保留。当各行都扫描以后仍没有找到,则放弃扫描,认为是键的误动作。 (3) 对得到的行号和列号译码,得到键值。 (4) 键的抖动处理。当用手按下一个键时,往往会出现所按键在闭合位置和断开位置之间跳几下才稳定到闭合状态的情况。在释放一个键时,也会出

25、现类似的情况,这就是键抖动,抖动的持续时间不一,通常不会大于10 ms,若抖动问题不解决,就会引起对闭合键的多次读入,对于键抖动最方便的解决方法就是当发现有键按下后,不是立即进行逐行扫描,而是延时10 ms后再进行。由于键按下的时间持续上百毫秒,延时后再也不迟。扫描函数的返回值为键特征码,若无键按下,返回值为0。程序如下:# include # define uchar unsigned char # define uint unsigned int void dlms( void )void kbscan( void ) ;void main ( void ) uchar key ;whil

26、e( 1 ) key =kbscan ( ) ; dlms( ) ; void dlms( void ) uchar i ; for ( i=200;i0;i- -) uchar kbscan ( void ) / 键扫描函数 uchar scode ,recode ; P1=oxf0 ; if ( (P1 & 0xf0 ) ! =0xf0 ) / 若有键按下 dlms ( ) ; / 延时去抖动 if ( P1 & 0xf0 )! = 0xf0 ) scode =0xfe ; / 逐行扫描初值 while ( scode & 0x10 ) !=0 ) P1=scode ; / 输出扫描码 i

27、f ( P1 & 0xf0 )! =0xf0 ) / 本行有键按下 recode= ( P1 & 0xf0 ) | 0x0f ; return ( scode ) + ( recode ) ) ; /返回特征字节码 else scode = ( scode 1) | 0x01 ; / 行扫描左移一位 return ( 0 ) ; 例5 七段数码显示与AT89C51的接口LED显示器工作在静态方式时,其阴极(或其阳极)点连接在一起接地(或+5 V),每一个的端选线(a,b,c,d,e,f,g,dp)分别与一个8位口相连。 LED显示器工作在动态显示方式时,段选码端口I/O1用来输出显示字符的段选

28、码,I/O2输出位选码。I/O1不断送待显示字符的段选码,I/O2不断送出不同的位扫描码,并使每位显示字符停留显示一段时间,一般为1-5 ms,利用眼睛的视觉惯性,从显示器上便可以见到相当稳定的数字显示。确定的8155片内4个端口地址如下:命令/状态口 : FFF0H口A: FFF1H口B: FFF2H口C: FFF3H6位待显示字符从左到右依次放在dis_buf数组中,显示次序从右向左顺序进行。程序中的table 为段选码表,表中段选码表存放的次序为0-F等。以下为循环动态显示6位字符的程序,8155命令字为07H。# include # include #define uchar unsigned char# define COM8155 XBYTE 0xfff0 #

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2