历史上的今天
今天是:2025年01月21日(星期二)
2020年01月21日 | 51单片机IO口模拟UART串口通信
2020-01-21 来源:eefocus
#include typedef enum { false, true }bool; #if 0 sbit Test_CLK = P0^3; //接收 脚定义 #endif bit RxdOrTxd = 0; //指示当前状态为接收还是发送 //通过嵌套宏定义,制作一张包括0~255各个数字中包含1的个数,其中包含偶数个1,则ParityTable256[i]=0,否则ParityTable256[i]=1; void SET_3v5v() void RST_SET(BitAction ResetState) PIN_RST = ResetState; void SET_CMVCC() uint16_t USART_ReceiveData(USART_TypeDef* USARTx) #if 1 static unsigned char cnt = 0; //位接收或发送计数 if (RxdOrTxd) #else void InterruptTimer0() interrupt 1{ static unsigned char cnt = 0; //位接收或发送计数
#include "main.h"
#include "smartcard.h"
#include "stdio.h"
sbit PIN_RXD = P1^0; //接收发送同一个引脚定义
sbit PIN_TXD = P1^0; //接收发送同一个发送引脚定义
sbit PIN_CLK = P3^1; //智能卡时钟引脚定义
sbit PIN_3v5v = P3^2; //智能卡3v_5v引脚定义
sbit PIN_RST = P3^3; //智能卡复位引脚定义
sbit PIN_CMDVCC = P3^4; //智能卡CMD引脚定义
#else
// test Parity
sbit PIN_RXD = P1^0; //接收 脚定义
sbit PIN_TXD = P1^2; //发送 脚定义
sbit PIN_CLK = P3^5; //智能卡时钟引脚定义
sbit PIN_3v5v = P3^2; //智能卡3v_5v引脚定义
sbit PIN_RST = P3^3; //智能卡复位引脚定义
sbit PIN_CMDVCC = P3^4; //智能卡CMD引脚定义
bit RxdEnd = 0; //接收结束标志
bit TxdEnd = 0; //发送结束标志
uint8_t RxdBuf = 0; //接收缓冲器
uint8_t TxdBuf = 0; //发送缓冲器
void ConfigUART(unsigned int baud);
void StartTXD(unsigned char dat);
void StartRXD();
void test_IO();
static const bool ParityTable256[256] =
{
#define P2(n) n, n^1, n^1, n
#define P4(n) P2(n), P2(n^1), P2(n^1), P2(n)
#define P6(n) P4(n), P4(n^1), P4(n^1), P4(n)
P6(0), P6(1), P6(1), P6(0)
};
void mainb(){
EA = 1; //开总中断
ConfigUART(9600);//配置波特率为 9600
while (1){
while (PIN_RXD); //等待接收引脚出现低电平,即起始位
StartRXD(); //启动接收
while (!RxdEnd); //等待接收完成
StartTXD(RxdBuf+1); //接收到的数据+1 后,发送回去
while (!TxdEnd); //等待发送完成
}
return;
}
{
PIN_3v5v=1;
}
void RESET_3v5v()
{
PIN_3v5v=0;
}
{
}
{
PIN_CMDVCC =1;
}
void RESET_CMVCC()
{
PIN_CMDVCC =0;
}
/* 串口配置函数,baud-通信波特率 */
void ConfigUART(unsigned int baud){
TMOD &= 0xF0; //清零 T0 的控制位
TMOD |= 0x02; //配置 T0 为模式 2
// TH0 = 256 - (11059200/6)/baud; //计算 T0 重载值
TH0 = 256 - (FOSC/12)/baud; //计算 T0 重载值
}
/* 启动串行接收 */
void StartRXD(){
while (PIN_RXD);
//printf("PIN_RXD2=0x%02Xrn", (int)PIN_RXD);
TL0 = 256 - ((256-TH0)>>1); //接收启动时的 T0 定时为半个波特率周期
ET0 = 1; //使能 T0 中断
TR0 = 1; //启动 T0
RxdEnd = 0; //清零接收结束标志
RxdOrTxd = 0; //设置当前状态为接收
}
/* 启动串行发送,dat-待发送字节数据 */
void StartTXD(uint8_t dat){
TxdBuf = dat; //待发送数据保存到发送缓冲器
TL0 = TH0; //T0 计数初值为重载值
ET0 = 1; //使能 T0 中断
TR0 = 1; //启动 T0
PIN_TXD = 0; //发送起始位
TxdEnd = 0; //清零发送结束标志
RxdOrTxd = 1; //设置当前状态为发送
}
{
/* Check the parameters */
// assert_param(IS_USART_ALL_PERIPH(USARTx));
/* Receive Data */
#if 0
uint16_t tt= USARTx->SR ;
USARTx->SR = tt & (uint16_t)0x3df; //wuhh add ,remove later
return (uint16_t)(USARTx->DR & (uint16_t)0x01FF);
#endif
return (uint16_t) RxdBuf;
}
void USART_SendData(USART_TypeDef* USARTx, uint8_t Data)
{
StartTXD(Data);
}
FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG)
{
FlagStatus bitstatus = RESET;
if (USART_FLAG== USART_FLAG_TC)
if (TxdEnd)
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
if (USART_FLAG== USART_FLAG_RXNE)
if (RxdEnd)
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
return bitstatus;
}
static bit polarity = 0; //输出智能卡时钟极性
/* T0 中断服务函数,处理串行发送和接收 */
void InterruptTimer0() interrupt 1{
Test_CLK = !Test_CLK;
{ //串行发送处理
cnt++;
if (cnt <= 8){ //低位在先依次发送 8bit 数据位
PIN_TXD = TxdBuf & 0x01;
TxdBuf >>= 1;
}else
if (cnt == 9)
{ //发送停止位
PIN_TXD = 1;
}
else{ //发送结束
cnt = 0; //复位 bit 计数器
TR0 = 0; //关闭 T0
TxdEnd = 1; //置发送结束标志
}
}
else{ //串行接收处理
if (cnt == 0){ //处理起始位
if (!PIN_RXD){ //起始位为 0 时,清零接收缓冲器,准备接收数据位
RxdBuf = 0;
cnt++;
}
else{ //起始位不为 0 时,中止接收
TR0 = 0; //关闭 T0
}
}else if (cnt <= 8){ //处理 8 位数据位
RxdBuf >>= 1; //低位在先,所以将之前接收的位向右移
//接收脚为 1 时,缓冲器最高位置 1,
//而为 0 时不处理即仍保持移位后的 0
if (PIN_RXD){
RxdBuf |= 0x80;
}
cnt++;
}else{ //停止位处理
cnt = 0; //复位 bit 计数器
TR0 = 0; //关闭 T0
if (PIN_RXD){ //停止位为 1 时,方能认为数据有效
RxdEnd = 1; //置接收结束标志
}
}
}
}
/* T0 中断服务函数,处理串行发送和接收 */
//test_IO();
#if 0
PIN_TXD = !PIN_TXD;
#else
if (RxdOrTxd){ //串行发送处理
cnt++;
if (cnt <= 8){ //低位在先依次发送 8bit 数据位
PIN_TXD = TxdBuf & 0x01;
TxdBuf >>= 1;
}else if (cnt == 9){ //奇偶位
PIN_TXD=ParityTable256[TxdBuf];
}else if (cnt == 10){ //发送停止位1 智能卡协议共两个停止位
PIN_TXD = 1;
}else if (cnt == 11){ //发送停止位2
PIN_TXD = 1;
}else{ //发送结束
cnt = 0; //复位 bit 计数器
TR0 = 0; //关闭 T0
TxdEnd = 1; //置发送结束标志
}
}else{ //串行接收处理
if (cnt == 0){ //处理起始位
if (!PIN_RXD){ //起始位为 0 时,清零接收缓冲器,准备接收数据位
RxdBuf = 0;
cnt++;
//printf("InterruptTimer 0n");
} else{ //起始位不为 0 时,中止接收
TR0 = 0; //关闭 T0
printf("InterruptTimer closen");
}
}
else if (cnt <= 8){ //处理 8 位数据位
RxdBuf >>= 1; //低位在先,所以将之前接收的位向右移
//接收脚为 1 时,缓冲器最高位置 1,
//而为 0 时不处理即仍保持移位后的 0
if (PIN_RXD){
RxdBuf |= 0x80;
}
printf("RxdBuf=0x%02Xrn", (int)RxdBuf);
cnt++;
}else{ //停止位处理
cnt = 0; //复位 bit 计数器
TR0 = 0; //关闭 T0
if (PIN_RXD){ //停止位为 1 时,方能认为数据有效
RxdEnd = 1; //置接收结束标志
}
}
}
#endif
}
#endif
史海拾趣
|
Linux是单体内核,即将图形、驱动及文件系统等功能全在操作系统内核中实现,运行在内核状态和同一地址空间,其优点是减少了进程间通信和状态切换的系统开销,获得较高的运行效率;缺点是内核比较庞大! WinCE是微内核,即在内核中实现基本功能, ...… 查看全部问答> |
|
void vSetMotorTimer(unsigned short uiTime)// uiTime us { RCAP2LH = uiTime; } //重新载入定时数据 void vUpdateMotorTimer(void) { T2LH=RCAP2L ...… 查看全部问答> |
|
有没有人研究过mini2440的BSP,其BSP是如何识别128M/256M等flash的? 因为我使用的是QQ2440,但是我发现最新的mini2440的BSP更新了很多驱动,我想移进去QQ2440使用,但是可惜烧写进去后不能启动。 我觉得想搞好这个bsp必须先知道如何使用其他flash时需要修改的代码,哪位高手知道的,麻烦指导下。… 查看全部问答> |
|
我是初学,最近被此问题困扰了好多天, 打开inputPanel后,改变输入法,inputPanel的高度会改变,此时如何捕获该事件。 我使用C#,开发环境vs 2005,.net CF 2.0。 希望解释能详细些,我是初学。 还有我的 ...… 查看全部问答> |
|
研究了N就,PG128128A资料到底怎么驱动,谁有能提供详细资料 12864及以下的我会,就是不会PG128128A的 邮箱 zoujun224@qq.com… 查看全部问答> |
|
请教大家有没有用过 5V和3.3V接口电压转换芯片,我需要DSP2812外接DS18B20和其他几个5V峰值的转速信号,需要做电平转换,但是不知道使用什么样的接口电压转换芯片,需要方向控制的就不要介绍了,比如:SN74LVC164245。我需要的是自动双向转换电平的 ...… 查看全部问答> |




