《蓝侨杯单片机编程笔记-胡昶威》由会员分享,可在线阅读,更多相关《蓝侨杯单片机编程笔记-胡昶威(34页珍藏版)》请在金锄头文库上搜索。
1、蓝桥杯单片机编程笔记一点说明本笔记为准备第六届蓝桥杯单片机组省赛时写下,其中知识点不乏有所错漏、理解偏颇,但都是经实际测试代码,仅用于应付比赛使用。作者:胡昶威QQ:10403859742015.3.25一、 IO 口编程 .1二、 数码管动态扫描和定时器 .3三、 矩阵键盘 .5四、 串口通讯和串口中断 .9五、 外部中断的使用 .14六、 实时时钟 DS1302 的使用 .14七、 PCF8591 与 IIC 总线的使用 .16八、 DS18B20 温度芯片的使用 .22九、 超声波传感器的使用 .23十、 步进电机与直流电机的使用 .26十一、 扩展:宏定义编程方法(推荐) .29十二、
2、 注意事项(常见编程错误) .33一、 IO 口编程IO 编程,该开发板使用了 573 锁存器,通过 P2 口的 5,6,7 位连接 3-8 译码器,扩展出了 8 个口,其中 4 个口分别连接 4 个 573 锁存器,这里以的锁存器来举例:原理图:分析代码:() ;其中,与进行与运算,高三位清零,其余位保持原来状态,不改变,即把控制译码器的高三位留出来:接着再或上;容易发现;或运算,与或结果为,与或结果不变,所以或上只需看的高三位,则高三位为,对应译码器的话,;所以输出;再经过与非运算,看下图示:则输出;即对应的锁存器的片选信号被选中,锁存器打通,接下来就可以对口进行操作,操作完之后,;高三位
3、直接清零,此时 Y4C=0,则把锁存器锁上了。类似的方法,数码管、蜂鸣器等都是如此操作,选中锁存器代码:P2=(P2&0x1f)|(这里填对应锁存器的位移号) ) 。二、 数码管动态扫描和定时器数码管显示分为段选和位选,数码管定义和显示函数:code unsigned char tab = 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90;unsigned char dspbuf=10,10,10,10,10,10,10,10;unsigned char dspcom=0;void display()/段选,消隐P2=(P2P0=0xff;P2
4、=P2/位选P2=(P2P0=(1sbit L1=P00;int main()IT0=1; /IT0=1,下降沿触发外部中断 0,IT0=0 边沿触发EX0=1;/使用外部中断 0EA=1;while(1)void Ex_int0() interrupt 0 /外部中断优先级最高P2=(P2L1=L1;P2=(P2其中,外部中断的引脚控制是 P32,P33,即对应独立按键的 S5,S4。六、 实时时钟 DS1302 的使用蓝桥杯提供函数,解释为:里面的命令和写入的数据可以看芯片手册:左侧的 READ、WRITE 分别是读写的命令,BIT7-BIT0 是要写入的数据,根据需要进行配置。DS130
5、2 只需记住这两个函数即可:Write_Ds1302( , )与 Read_Ds1302(x) ,配置看手册。重点:芯片表说明:第一行:秒-因为秒的范围是 0-59,所以 6,5,4 位表示秒的十位,3,2,1,0 表示个位,十位最大是 5,所以三位即可。第二行:跟上面一样;第三行:7 位:1 为 12 小时制,0 为 24 小时制;5 位:12 小时制时为 0表示上午,1 表示下午,24 小时制时,和 4 位一起表示小时的十位;其余的时间一样的表示。倒数第二行:只看 7 位:为 1 时禁止写数据,所以开始写数据时必须置0;读数时:!需要加“写操作这一行代码” 。读的话直接按照命令读即可。DS
6、1302 进阶( BCD 码转换):解决之前 60 秒不能进位的问题。1) 写入初始值时,要把 10 十进制数转换为码,例:写入时间: Ds1302_Single_Byte_Write(0x8e, 0x00);/写操作Ds1302_Single_Byte_Write(0x85, (17/10)4)*10 + (ReadValue八进制转十进制-ReadValue=Ds1302_Single_Byte_Read(0x85);hour=(ReadValue!(这句一定不要省) Ds1302_Single_Byte_Write(0x00, 0x00);/写操作ReadValue=Ds1302_Sin
7、gle_Byte_Read(0x83);minute=(ReadValueDs1302_Single_Byte_Write(0x00, 0x00);/写操作ReadValue=Ds1302_Single_Byte_Read(0x81);sec=(ReadValueDs1302_Single_Byte_Write(0x00, 0x00);/写操作显示:dspbuf0=hour/10;dspbuf1=hour%10;dspbuf2=minute/10;dspbuf3=minute%10;dspbuf4=sec/10;dspbuf5=sec%10;七、 PCF8591 与 IIC 总线的使用(1)
8、IIC 总线的使用:比赛提供了 IIC 的两个库文件,IIC.h;IIC.c ,其中需要注意的函数是:其中,该函数是初始化的,当使用 AD 转换的时候需要在 main 函数开始时调用,该函数内部只需看这句代码即可:i2c_sendbyte(0x03);/ADC 通道 3,板上有 4 个模拟输入口,分别为 0,1,2,3;设置哪一个模拟输入口就是根据这句代码,0x03 表示通道 3,这是根据芯片手册配置的,如图:8 位前 6 位不用管,都为 0,最后两位就是配置选择哪一个通道的。第二个函数:读取 AD 转换后的数值,这个函数直接调用就可以了,函数内部如何实现不用管,但是需要注意的是:该函数扫描调
9、用最好是100ms。第三个函数,上面的都是 AD 转换,即模拟信号转数字信号,下面这个函数是 DA 转换,数字信号转换成模拟信号,就是单片机输出数字信号,用万能表去量单片机引出的引脚,量一下电压大小,这个估计比赛不会考,不过预防万一:该函数和上面两个函数分离开来的,一、二函数是要在一起使用,初始化后之后才能调用,第三个加入头文件,直接调用即可,比较简单!!上面说法有误,A/D 转换的初始化函数和读取转换后的数值都需要自己写。这里了解一下 PCF8591 只需根据时序格式发送地址字节和控制字节: ,这是地址字节,其中 A2,A1,A0 硬件已经接地,故都为 0,最低位表示的是你要从 IIC 总线
10、上读数还是写数据,1 表示读, 0 表示写,即读数据发的地址是:0x91;写数据发的地址是 0x90;控制字节:由芯片资料知,控制字节有 8 位,有两位固定是 0,除了第 0、1位需要自己设置,其他的我们都设为 0,那些位都是一些具体的功能,我们暂时用不着,不用管先,第 0、1 位是模拟通道选择,PCF8591 上提供了 4 路模拟通道,根据需求进行选择,如选择通道 3 即发送控制字节:0x03;地址字节和控制字节都明白了,接下来根据时序要求进行配置,A/D 转换需要一个初始化函数:Init_ADpcf8591(); 和一个获得 AD转换后的数值的函数:adc_pcf8591(); 其中初始化
11、函数的作用是发送 AD 转换的控制字节;adc_pcf8591()发送读取得地址并读回数据,先写指令才能读;格式如下:这个是初始化的协议:分别是 startIIC、 (地址写)发送 0x90、等待应答、发送控制字节(AD 这里是选择通道的指令,如选择通道3,0x03)0x03、等待应答、 (达到目的,没有后续的操作,直接停止总线)StopIIC.初始化的函数就是如此写;adc_pcf8591 的协议:依次是:startIIc、发送读地址 0x91、等待应答、读回 AD 转换后的数值、读回后发送应答给 PCF8591,表示收到,并且不需要再返回应答,要传参数 1,如图红圈示,即函数 Ack(1)
12、;、最后stopIIC 总线。D/A 转换(其实挺麻烦,先前太自信了,哈):所谓 D/A 转换其实就是把数字信号转换成模拟信号输出,用单片机发数字通过 D/A 转换成电压输出,检测的方法可以用电压表测量。配置的方法跟 A/D 类似,先发地址字节,再发控制字节,然后把数字发出去(AD 这里是接收模拟信号,是相反的机制) 。控制字节:如图示,控制字节的第 6 位是 1 的话是模拟输出模式,其余位全为 0,发送格式跟 AD 一样:代码如一开始图示。(2) EEPROM 的使用,AT24C02 ,可以掉电依旧保存上一次操作的数据,下次上电后接着运行。需要注意两个函数,一个是写进 EEPROM 里面保存
13、,再次上电再从里面读回来:其中写函数需要指定 AT24C02 的地址以及需要写入的数据,读函数要想取回写进的数据,需要从相同的地址里面读:其中 AT24C02 的存储地址是 0x00,可以是其他地址,如 0x02,但是读和写的地址必须一致。写与读的协议与 AD 或相同,由芯片资料及原理图知()的写地址为;读地址为;注意:读数的时候读出一个数之后发送一个应答信号,若()表示还想继续读下一个字节,若() ;则不想再读数,让停止发送。八、 DS18B20 时钟芯片的使用比赛有提供代码,只需记住这个函数:读取温度值,整数(其中,提示 EA 总中断要打开、关闭,也可以不用 ) 。浮点数的表示。注意,只有
14、提供函数,没有提供读取温度的函数,即上面的那个,只有下面: 这几个函数。编写读取温度的函数需要记住 DS13B20 的三条指令,0xCC, 跳过 ROM 检测;然后启动温度转换:0x44; 转换需要时间,这里精确延时Delay_OneWire(200);然后再次初始化,再次执行跳过,然后读取温度指令:0xBE.;注意读出的温度是低字节先,然后才是高字节,分别用两个变量保存还要通过公式转换成我们需要的整数或浮点数。完整代码如上图示。九、 超声波传感器的使用#include reg52.h /定义 51 单片机特殊功能寄存器#include intrins.h#include absacc.h/12M 用这个/*#define somenop _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_n