七 安全可靠的校验Word格式.docx
- 文档编号:4871749
- 上传时间:2023-05-04
- 格式:DOCX
- 页数:11
- 大小:19.62KB
七 安全可靠的校验Word格式.docx
《七 安全可靠的校验Word格式.docx》由会员分享,可在线阅读,更多相关《七 安全可靠的校验Word格式.docx(11页珍藏版)》请在冰点文库上搜索。
把单片机串口通讯的那两个引脚经过一个MAX3232之后直接跟电脑的9针串口通讯。
我发现很多朋友会选MAX232这个芯片,而我本人更加推荐用MAX3232。
因为MAX232只支持5V,不是宽压的,而MAX3232不但支持5V,还支持3V。
每个人的记忆力都很宝贵,用232串口我只选MAX3232,不管它是用5V工作还是3V工作。
就像74系列的芯片,我的心中只有你(74HC)没有它(74LS),一样的道理,74HC是宽压,74LS不是宽压。
(4)源码适合的单片机:
PIC18f4520,晶振为22.1184MHz,波特率115200
(5)源代码讲解如下:
#include<
pic18.h>
//包含芯片相关头文件
//补充说明:
吴坚鸿程序风格是这样的,凡是输出IO后缀都是_dr,凡是输入的//IO后缀都//是_sr
#define
beep_dr
LATA2
//蜂鸣器输出
吴坚鸿程序风格是这样的,凡是做延时计数阀值的常量
//前缀都用cnt_表示。
#definecnt_voice_time
150
//蜂鸣器响的声音长短的延时阀值
#definecnt_send
300
//确保接收缓冲区没有继续接收数据,是变量
//send_cnt的溢出阀值
Voidusart_service();
//串口通讯服务程序,放在main函数里
unsignedcharasy_recieve();
//把串口缓冲区的数据一个个提取出来
voideusart_send(unsignedchart_data);
//串口发送一个字节的数据
VoidBuf_clear();
//把余下的缓冲区清零
voidDelay11(unsignedintMS);
//延时函数
吴坚鸿程序风格是这样的,凡是计数器延时的变量
//后缀都用_cnt表示。
unsignedintvoice_time_cnt;
//蜂鸣器响的声音长短的计数延时
unsignedintsend_cnt=0;
//一串数据从上位机发过来的时候,他们每个字节之间//的延时间隔很短,如果他们的延时间隔一旦超过了这个send_cnt变量的延时,那么就////认为他们的一串数据已经发送完毕
吴坚鸿程序风格是这样的,凡是涉及统计数量的变量
//后缀都用_total表示。
unsignedintRCREG_total;
//统计串口缓冲区已经收了多少个数据
unsignedintRCREG_read_total;
//统计已经从串口缓冲区读出了多少个数据
unsignedcharvalid_total;
//一串数据中的有效数据总量
吴坚鸿程序风格是这样的,凡是用来更新的标识变量,比如液晶刷屏,或者有新接收的串口数据更新等等,后缀一律用_update表示
Unsignedcharsend_update=0;
//一旦有数据从上位机发送过来,就会引发串口接收中////断,在串口中断里,我把send_update=1表示目前正在接收数据,警告单片机先不要//猴急,等串口中断把所有从上位机连续发送过来的一堆数据接收完,再处理。
那么什么///时候才知道发送的数据已经发送完毕了呢?
用send_cnt识别。
因为在串口中断里,我///每次都会把send_cnt=0,而在main函数里,一旦发现send_update==1,send_cnt就//会开始自加,当它超过某个数值的时候,就会自动把send_update=0,表示目前已经没//有数据发送了。
而如果有数据不断从上位机传来,send_cnt永远也不会超过某个数值,//因为每个中断它都被清零,这个原理跟看门口狗喂狗的原理很像。
吴坚鸿程序风格是这样的,凡是用来接收数据的缓冲区数组后缀都用_buf表//示
UnsignedcharRCREG_buf[50];
//串口接收缓冲区,读者可以根据实际项目设置大小
UnsignedcharRCREG_buf_temp[50];
//临时处理串口数据的缓冲区,可以不用那么大
吴坚鸿程序风格是这样的,凡是自锁变量名,后缀都用_lock表示。
Unsignedcharsend_lock=0;
吴坚鸿程序风格是这样的,凡是在main函数中用的中间变量,前缀m_,后//缀用_char或者_int表示类型
Unsignedintm_int;
//中间变量,只要是用在main函数里,谁都可以重复用。
Unsignedcharreceive_sum;
//一串数据中的累加和,注意,必须定义成字节变//量,这样运算中它会自动丢弃超过一个字节的位。
//主程序
main()
{
ADCON0=0x00;
ADCON1=0x0f;
//全部为数字信号
ADCON2=0xa1;
//右对齐
RBPU=0;
//上拉电阻
SSPEN=0;
//决定RA5不作为串口
TRISA2=0;
BRG16=0;
//设置串口通信寄存器
BRGH=0;
SPBRGH=0x00;
SPBRG=0x02;
//22.1184MHz晶振,115200波特率
SYNC=0;
SPEN=1;
TX9=0;
TXEN=1;
TXIF=1;
RX9=0;
CREN=1;
RCIE=1;
PEIE=1;
GIE=1;
T1CON=0x24;
//定时器中断配置
TMR1H=0xFE;
TMR1L=0xEF;
TMR1IF=0;
TMR1IE=1;
TMR1ON=1;
//补充说明,以上的内容为寄存器配置,每种不同的单片机会有点差异,
//大家不用过度关注以上寄存器的配置,只要知道有这么一回事即可
beep_dr=0;
//关蜂鸣器,上电初始化IO
while
(1)
CLRWDT();
//喂看门狗,大家不用过度关注此行
usart_service();
//串口通讯服务
}
//中断
voidinterrupttimer1rbint(void)
if(RCIE==1&
&
RCIF==1)
//串口中断,一次只能接受一个字节
RCIE=0;
RCIF=0;
++RCREG_total;
//以下代码是鸿哥的在所有串口项目中用到的标准代码
if(RCREG_total>
50)
//超过缓冲区
RCREG_total=50;
RCREG_buf[RCREG_total-1]=RCREG;
//依次把上位机来的数据存入数组缓冲区
send_update=1;
//通知单片机目前正在接收数据
send_cnt=0;
//及时喂狗,虽然main函数那边不断在累加,但是只要串口的数//据还没发送完毕,那么它永远也长不大,因为每个中断都被清零,很可怜。
RCIE=1;
if(TMR1IE==1&
TMR1IF==1)
//定时中断
TMR1IF=0;
//定时中断标志位关闭
TMR1ON=0;
//定时中断开关关闭
if(voice_time_cnt)
//控制蜂鸣器声音的长短
beep_dr=1;
//蜂鸣器响
--voice_time_cnt;
else
{
Asm(“nop”);
//添加此行空指令为了使else的内容跟if的内容对称,意义////不大
beep_dr=0;
//蜂鸣器停止
}
TMR1H=0xFe;
//重新设置定时时间间隔
TMR1L=0x00;
TMR1ON=1;
//定时中断开关打开
voidusart_service()
//串口服务程序,在main函数里
if(send_update==1)
//说明目前串口正在接收数据,不要读缓冲区数据
send_lock=1;
//开自锁标志
++send_cnt;
//只要有数据接收,send_cnt每次都被串口中断清零
if(send_cnt>
cnt_send)
//延时一段时间,确认缓冲区没有继续接受数据
send_update=0;
Else
//说明当前没有继续接收数据了
if(send_lock==1)
//在数据已经接收完毕,并且还没有处理过数据的情况下
send_lock=0;
//处理一次就锁起来,不用每次都进来,除非有新接收的数据
while(RCREG_read_total<
RCREG_total)
//说明还没有把缓冲区的数据读取完
RCREG_buf_temp[0]=RCREG_buf_temp[1];
//数据移动,方便截取关键字
RCREG_buf_temp[1]=RCREG_buf_temp[2];
RCREG_buf_temp[2]=asy_recieve();
if(RCREG_buf_temp[0]==0xeb&
RCREG_buf_temp[1]==0x00&
RCREG_buf_temp[2]==0x55)
//数据头”eb0055”判断
//把余下有效的数据都取出来
RCREG_buf_temp[3]=asy_recieve();
//数据量
Valid_total=RCREG_buf_temp[3];
For(m_int=0;
m_int<
Valid_total;
m_int++)
//提取有效数据
RCREG_buf_temp[4+m_int]=asy_recieve();
RCREG_buf_temp[4+Valid_total]=asy_recieve();
//自带校验和
Receive_sum=0;
//累加校验和计算
(Valid_total+4);
Receive_sum=Receive_sum+RCREG_buf_temp[m_int];
If(Receive_sum==RCREG_buf_temp[4+Valid_total])
//校验和正确
RCREG_buf_temp[0]=0;
//把临时处理数据清零,方便下次接收
RCREG_buf_temp[1]=0;
RCREG_buf_temp[2]=0;
eusart_send(0x00);
//串口发送多一个填充无效字节,避免硬件原因引起第一个字节丢失
eusart_send(0xeb);
//串口发送应答的数据
eusart_send(0xaa);
voice_time_cnt=cnt_voice_time;
//蜂鸣器响“滴”一声就停
//校验和出错
eusart_send(0x55);
break;
//退出循环
Buf_clear();
//把余下的缓冲区清零,方便下一堆数据接收与处理
VoidBuf_clear()
Unsignedcharbuf_clear_temp;
buf_clear_temp=asy_recieve();
unsignedcharasy_recieve()
unsignedcharRCREG_dt;
++RCREG_read_total;
//已经读出了多少个数据
RCREG_dt=RCREG_buf[RCREG_read_total-1];
if(RCREG_read_total>
=RCREG_total)//只要把全部数据都读完,马上把缓冲区清零
RCREG_read_total=0;
RCREG_total=0;
returnRCREG_dt;
voideusart_send(unsignedchart_data)//串口发送一个字节的数据
unsignedinterror_delay;
TXREG=t_data;
//发送数据
error_delay=0;
//等待把数据发送完毕
//这里也可以省略,直接用延时替代
if(TXIF==1)
++error_delay;
if(error_delay>
200)
//超时也要退出,不能死等
Delay11
(1);
//此处最玄机,要特别注意。
每发送完一个字节,由于不同的项目,这//里的延时间隔都不一样,读者根据实际情况来改。
这里最容易出问题,必须要延时,尤其是连续发送一堆数据的时候。
读者也可以自己把这种死延时改成计数延时的方式。
//延时函数
voidDelay11(unsignedintMS)
unsignedcharus,usn;
while(MS!
=0)
//for12M
{
usn=2;
while(usn!
=0)
CLRWDT();
us=0xf5;
while(us!
=0){us--;
};
usn--;
MS--;
(6)小结:
累加和就是把前面所有字节相加,然后把结果放在一个字节的变量上,超过一个字节范围的部分会自动丢弃。
(未完待续,下节更精彩,不要走开哦
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 安全可靠的校验 安全 可靠 校验