基于普中的stc89c52,
串口:
通讯接口,51单片机自带UART(通用异步收发器),可实现窗口通讯。
硬件电路:
简单双向串口通信有两根通信线(发送端TXD和接收端RXD),TXD和RXD需要交叉连接,单向数据传输时,可以接一根通信线,电平协议不一致,需要加电平转换芯片。
电平标准:
电平标准是数据1和数据0的表达方式,是传输线缆中人为规定的电压与数据的对应关系,串口常用的电平标准有三种:
TTL电平:+5v表示1,0v表示0;
RS232电平:-3~-15V表示1,+3~+15V表示0;
以上电平距离十多米以上传输信号就会错乱;
RS485电平:两线压差+2~+6V表示1,-2~-6V表示0;(差分信号)
RS485传输距离远;
流控制,调整传输速率和接收速率不匹配的情况;
同步的带时钟线:SCL,SCLK
全双工:两根线,设备a和设备b可以同时发;
半双工:一根线,利用同一根线收发;分时复用一根线
单工:只能单向传输;
51单片机里的UART:
串口参数及时序图:
波特率:串口通信的速率(发送和接收各数据位的间隔时间)
检验位:用于数据验证(奇偶校验,)
停止位:用于数据帧间隔
比特率:bit,传送多少位;
串口模式图:
配置ES,EA;
波特率计算:
-----------------------------------------------------
SCON = 0x40;//模式一,SM0=0,SM1=1;
PCON |= 0x80;//波特率
TMOD &= 0x0F; //设置定时器模式
TMOD |= 0x20; //设置定时器模式,八位自动重装
TL1 = 0xF3; //设置定时初值,和波特率有关
TH1 = 0xF3; //设置定时初值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
---------------------------------------------------------
以12MHZ的晶振为例(每过1微秒记一次数,)
定时器为0xF3(十进制为243),八位寄存器,每隔256溢出一次,与初始值相差13个数(每记13个数溢出一次),每隔13微秒溢出一次,TI的溢出率即为1/13= 0.07692307692307692307692307692308 MHZ
SMOD = 1:
1/13= 0.07692307692307692307692307692308 MHZ / 16 =4,807.6923076923076923076923076923 HZ
频率没有与晶振对应,所以会产生误差;
误差值为溢出率/波特率
0.07692307692307692307692307692308 / 4,807.6923076923076923076923076923
=1.6000000000000000000000000000001e-5
所以会产生0.16/100的误差;
如果不选择SMOD就先 / 2再 / 16;
串口相关寄存器:
PCON(电源寄存器)前两位与串口有关;
串口控制寄存器SCON和PCON:
配置目标:让UART处于模式1工作状态;(模式1:8位UART)
SCON = 0x40 //SM0:0;SM1:1;//模式一给二进制位:0100 0000;十六进制0x40;
PCON=0 /波特率配置;
------------------配置定时器
串口中定时器有自己的工作模式;
-----------------------------------------------------
SCON = 0x40;//模式一,SM0=0,SM1=1;
PCON |= 0x80;//波特率
TMOD &= 0x0F; //设置定时器模式
TMOD |= 0x20; //设置定时器模式,八位自动重装
TL1 = 0xD0; //设置定时初值,和波特率有关
TH1 = 0xFF; //设置定时初值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
---------------------------------------------------------
定时器和波特率stc配置样例:
发送速率过快或者波特率过高都会产生误差,可以采用低波特率和Delay延迟函数解决;
配置单片机收数据:
把REN置为1;
SCON = 0x50;//模式一,SM0=0,SM1=1;
PCON |= 0x80;//波特率
TMOD &= 0x0F; //设置定时器模式
TMOD |= 0x20; //设置定时器模式,八位自动重装
TL1 = 0xD0; //设置定时初值,和波特率有关
TH1 = 0xFF; //设置定时初值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
EA = 1;//启动中断
ES = 1;//启动串口中断;
中断号:
void UART_Routine() interrupt 4 串口中断号4
单片机是用同一个串口同时收发:所以在中断函数里面用if判断是接收中断还是发送中断;
一个函数不能再主函数和中断函数中同时调用;
数据显示模式:
HEX模式/二进制模式:以原始数据形式显示;
文本模式/字符模式:以原始数据编码后的数据显示;
数据在文本模式时需要用ascll码进行编码在进行发送,可以传输的数据为0-255;(对应ascll码表)
在实际传输过程中只传输二进制码,只是显示方式不一样;
LED点阵屏:
本次使用的开发板只是一个8*8单色点阵;
显示原理:
类似于数码管,点阵屏只能扫描法显示不同内容;
74HC595(可控制多位输出):
QA--QH输出端;
OE上加横线说明低电平有效;OE使能接口(只有OE低电平芯片才工作);
RCLK:寄存器时钟;
SRCLR:串行清零端 (直接接VCC代表不清空)
SRCLK:串行时钟
SER:串行数据
--------------------------------------------
SER:串行数据:
数据分串行(一个一个在时钟的激励下出去)和并行(同时输出)
串行数据接移位寄存器:把数据写入高电平,控制时钟上升沿移位(SERCLK),把SER清零,再给一个上升沿移位,,数据会一个一个向下移动;
RCLK会把移位寄存器的数据移位到输出端(给RCLK一个上升沿)
以上是一片74HC595的工作方式;
QH` 多片级联:
当移位寄存器满的时候,SER继续给1,输出端会输出到QH`给下一个移位寄存器;
每一片移位寄存器的时钟是连接到一起的;当所有的移位寄存器满的时候,数据移位完成是,上升沿锁存(RCLK)会控制所有的移位寄存器输出到输出缓冲区;
单片机低电平强,高电平弱,如直接接芯片IO口会影响亮度;如果用三极管放大电路进行放大输出电平,IO口作为控制电路,这样缓冲后可以增加导通效果;
同一列输出和同一行输出灯亮度不一样;(恒压输出和恒流输出);
c51中的sfr、sbit:(在头文件中可以找到)
sfr:特殊功能寄存器声明;
例如:sfr P0 =0x80; 声明P0口寄存器,物理地址为0x80;
sbit:特殊位声明
例如:sbit P0_1 = 0x81; 或 sbit P0_1 = P0^1; /声明P0寄存器的第一位;
可位寻址/不可位寻址:
单片机系统中,操作任意寄存器或者某一位数据时,必须给出其物理地址,又因为一个寄存器里有八位,所以位的数量是寄存器数量的8倍。单片机无法对所有位进行编码,故每8位寄存器中,只有一个是可以寻址的,对不可寻址的寄存器,若只操作其中一位而不影响其他位,可以用“&=”,“|=”,“^=”的方法进行位操作;
-----------------------------
sbit RCK = P3^5; //把P3的第五位命名为RCLK,,等同于操作P35
采用不同的命名方法:来保证避免命名冲突;
高位优先推入QH:
SER第一个给最高位值;把byte的最高位取出赋值给SER;
单片机初始化后所有的IO口都是高电平:所以要操作sck要把先赋值为0;
上升沿移位由0置1后SER给的高位1被移入下一层,移动结束后,再次置0,为下一次移动准备;
重复移位:
用for循环解决:
上升沿移位完成后,进行上升沿锁存,把八位数据送到IO口上;
点阵屏代码:
当Column = 0 ,P07 = 0.其他输出1;
代码改进:
段选 位选 段选 位选 段选 位选 //点阵屏重复执行,会把位选的数据影响到段选数据;所以要消影;
消除残影,所以加上延时 位清零