本文主要是介绍软件串口接收子程序,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
代码;
stduart.c
/*《AVR专题精选》随书例程3.通信接口使用技巧项目:使用延时法实现半双工软件串口文件:sfuart.c说明:软件串口驱动文件作者:邵子扬时间:2012年12月13日*/
#include "sfduart.h"// 循环中延时调整系数
#define SFD_LOOP_VAR 12// 软件串口初始化
void sfdUART_init(void)
{PINDIR(sfdUART_TXDIO, PIN_OUTPUT);PINSET(sfdUART_TXDIO);PINDIR(sfdUART_RXDIO, PIN_INPUT);PINSET(sfdUART_RXDIO);
}// 读取一个字节
char sfdUART_getbyte(void)
{unsigned char i, tmp;// 起始位while(PININ(sfdUART_RXDIO));// 延时 1.5 比特位_delay_us(1500000UL / sfdBAUDRATE);// 读取8位数据for(i = tmp = 0; i < 8; i++){tmp = tmp >> 1;if(PININ(sfdUART_RXDIO))tmp |= 0x80;// 循环中,延时函数需要调整时间,去掉循环语句本身占用时间_delay_us(1000000UL / sfdBAUDRATE - SFD_LOOP_VAR);}// 1个停止位_delay_us(1000000UL / sfdBAUDRATE);return tmp;
}// 发送一个字节
void sfdUART_sendbyte(char dat)
{unsigned char i;// 起始位PINCLR(sfdUART_TXDIO);_delay_us(1000000UL / sfdBAUDRATE);// 8位数据位for(i = 0; i < 8; i++){if(dat & 0x01)PINSET(sfdUART_TXDIO);elsePINCLR(sfdUART_TXDIO);dat = dat /2;// 延时时间需要根据循环中指令数量进行调整// 去掉指令占用时间,这个时间与指令数和时钟频率有关_delay_us(1000000UL / sfdBAUDRATE - SFD_LOOP_VAR);}// 停止位PINSET(sfdUART_TXDIO);_delay_us(1000000UL / sfdBAUDRATE);}
main.c
/*《AVR专题精选》随书例程3.通信接口使用技巧项目:使用延时法实现半双工软件串口文件:main.c说明:软件串口的使用方法作者:邵子扬时间:2012年12月13日*/
#include "cfg.h"
#include "macromcu.h"
#include "sfduart.h"#include <avr/io.h>// 计算波特率
#define UBRRREG (F_CPU / ( 8 * sfdBAUDRATE ) - 1)const char msg[]="Input here> ";// 初始化
void init()
{int tmp;// 初始化软件串口sfdUART_init();// 初始化硬件串口// 使用硬件串口进行对比UBRRH = UBRRREG / 256;UBRRL = UBRRREG % 256;UCSRA = ( 1 << U2X );UCSRB = ( 1 << TXEN );UCSRC = ( 1 << UCSZ1) | ( 1 << UCSZ0 );// 显示提示消息tmp = 0;while(msg[tmp]){sfdUART_sendbyte(msg[tmp]);tmp++;}
}int main(void)
{char tmp;init(); // 初始化for(;;){tmp = sfdUART_getbyte(); // 等待串口输入数据UDR = tmp; // 发送到硬件串口sfdUART_sendbyte(tmp); // 通过软件串口返回数据// 可以对比两个串口的数据// 以及波形}return 0;
}
仿真效果图
这篇关于软件串口接收子程序的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!