Ⅰ 51单片机UART连续发送问题
在uart_send(i);后面加一个短延时看看。
再看一下你的晶振是不是11.0592MHz。
ES = 1;改成ES =0;
Ⅱ 51单片机内置uart硬件
51内置UART是硬件的,IO不能变化。如果你不想使用P3.0、P3.1,就只能在其它IO上通过程序来模拟UART了。
Ⅲ 51单片机uart接收数据出错
电压设定问题。
UART所在的Bank中的电压设定为3.3v,而根据开发板原理显示应该设定为1.8v。在UART_RX中接收时,由于在FPGA一端给的电压为3.3v,因此可以满足1.8v的电压要求,数据可以正常的发送给UART,但是在UART一端发送数据给FPGA时,由于FPGA给的电压标为3.3v,要想为导通状态,即拉高状态,电压最低为2.4v才行,但是给UART1提供的电压只有最高1.8v,这样就会不满足3.3v的电压要求,就会一直为低的状态,数据就会出错。
通用异步收发传输器,通常称作UART。它将要传输的资料在串行通信与并行通信之间加以转换。作为把并行输入信号转成串行输出信号的芯片,UART通常被集成于其他通讯接口的连结上。
Ⅳ 51单片机中的串行接口和全双工的UART分别是指什么
串行接口是指数据一位位地顺序传送,常用的有RS232和RS485;
UART是异步串行接口,即是主从机时钟频率不同步,通信是通过设置波特率实现的。
UART其实就是串行接口中的一种。
通信有串行、并行之分,而串行通信又有同步、异步之分。
同步常用协议是SPI、IIC。异步就上面说的。
Ⅳ 51单片机与uart通信
//51串口通信基本设置我不讲了,网上泛滥得很,基本通信调通的基础上通过命令来控制单片机动作可以用以下的方法,很简单。
//串口中断处理,接收用数组RecCmd[],调试助手每次发送数据的最后两个字符是'\r'和'\n'
//接收一个命令完成后将接收的内容放入缓冲RecCmdBuf[]
extern uchar idata RecCmd[10],RecCmdBuf[10]; //串口接收双缓冲,最大接收9个有效字节,第10个是’\r‘
extern bit RecCmdFlag;
void ISR_SERIAL(void) interrupt 4 using 2
{
uchar i;
if(RI) //RI接受中断标志
{
RI = 0; //清除RI接受中断标志
i = SBUF; //SUBF接受/发送缓冲器
SBUF= i; //RecCmd[RecPtr]; Echo Back
unReadyToSend = 1; //与另一个非echo发送程序之间的互锁信号
if('\n' == i) //收到‘\n'字符表示调试助手已经发送完成
{
i = 0;
while(('\r' != (RecCmdBuf[i] = RecCmd[i])) && i<10)
{
i++; //已接收部分放入缓冲
}
if(i) //避免调试助手发空内容,即只发'\r'和'\n'
RecCmdFlag =1; //通知主程序命令接收完成
RecPtr = 0; //准备接收新命令
}
else
{
RecCmd[RecPtr++] = i;
if(RecPtr>9)
RecPtr = 0; //超长无效命令
}
}
if(TI)
{
TI = 0; //发送中断响应
unReadyToSend = 0;
}
}
//命令处理部分可以放在主循环里调用,命令判断的方式非常原始,但自己测试用就无所谓
void SerialCmdHandle(void)
{
if(RecCmdFlag)
{
if('m' == RecCmdBuf[0] && 'e' == RecCmdBuf[1] && 'n' == RecCmdBuf[2] && 'u' == RecCmdBuf[3] && '\r' == RecCmdBuf[4])
ShowMenu(); //command "menu"
if('s' == RecCmdBuf[0] && 'h' == RecCmdBuf[1] && 'o' == RecCmdBuf[2] && 'w' == RecCmdBuf[3] && ' ' == RecCmdBuf[4] && 's' == RecCmdBuf[5] && '\r' == RecCmdBuf[6])
{
LedShow = Serial; //command "show s"
}
if('s' == RecCmdBuf[0] && 'h' == RecCmdBuf[1] && 'o' == RecCmdBuf[2] && 'w' == RecCmdBuf[3] && ' ' == RecCmdBuf[4] && 'a' == RecCmdBuf[5] && 'd' == RecCmdBuf[6] && '\r' == RecCmdBuf[7])
{
LedShow = Adc; //command "show ad"
}
if('s' == RecCmdBuf[0] && 'h' == RecCmdBuf[1] && 'o' == RecCmdBuf[2] && 'w' == RecCmdBuf[3] && ' ' == RecCmdBuf[4] && 't' == RecCmdBuf[5] && 'e' == RecCmdBuf[6] && '\r' == RecCmdBuf[7])
{
LedShow = TempCov; //command "show te"
}
if('s' == RecCmdBuf[0] && 'h' == RecCmdBuf[1] && 'o' == RecCmdBuf[2] && 'w' == RecCmdBuf[3] && ' ' == RecCmdBuf[4] && 't' == RecCmdBuf[5] && 'i' == RecCmdBuf[6] && '\r' == RecCmdBuf[7])
{
LedShow = Time; //command "show ti"
}
if('s' == RecCmdBuf[0] && 'h' == RecCmdBuf[1] && 'o' == RecCmdBuf[2] && 'w' == RecCmdBuf[3] && ' ' == RecCmdBuf[4] && 't' == RecCmdBuf[5] && 'd' == RecCmdBuf[6] && '\r' == RecCmdBuf[7])
{
LedShow = Date; //command "show td"
}
if('s' == RecCmdBuf[0] && 't' == RecCmdBuf[1] && ' ' == RecCmdBuf[2] && '\r' == RecCmdBuf[9])
{
//command "st 000012" 改变ds1302的时间 ss:mm:hh //24hour |0x80
SetClockTime((((RecCmdBuf[3]-'0')<<4) | (RecCmdBuf[4]-'0')),(((RecCmdBuf[5]-'0')<<4) | (RecCmdBuf[6]-'0')),(((RecCmdBuf[7]-'0')<<4) | (RecCmdBuf[8]-'0')));
}
if('s' == RecCmdBuf[0] && 'd' == RecCmdBuf[1] && ' ' == RecCmdBuf[2] && '\r' == RecCmdBuf[9])
{
//command "sd 011299"改变ds1302的日期 dd:mm:yy
SetClockDate((((RecCmdBuf[3]-'0')<<4) | (RecCmdBuf[4]-'0')),(((RecCmdBuf[5]-'0')<<4) | (RecCmdBuf[6]-'0')),(((RecCmdBuf[7]-'0')<<4) | (RecCmdBuf[8]-'0')));
}
LedChangeFlag = 1;
//LcdChangeByteFlag = 0 + CHANGE + SERIAL;
RecCmdFlag = 0;
}
}
//下面是一个串口输出的menu菜单,给你参考。
void SendOneByte(uchar ch)
{
//ES = 0; //禁止发送中断
SBUF = ch;
unReadyToSend = 1; //互锁信号
}
void UartSendST(uchar *st, uchar len)
{
while(len > 0)
{
while(unReadyToSend);
SendOneByte(*st++);
len--;
}
}
typedef struct _menu{
uchar *item;
uchar size;
} T_Menu;
T_Menu code MAINM = {"MENU\r\n",6}, \
MENU0 = {"_____________________________________\r\n",39}, \
MENU1 = {"menu-> list this menu\r\n",23}, \
MENU2 = {"show s/ad/te/ti/td-> \r\n",19}, \
MENU3 = {"serial/ad-da/temp/time/date\r\n",29}, \
MENU4 = {"led f num-> led flash time us\r\n",31}, \
MENU5 = {"st ssmmhh->set time\r\n",21}, \
MENU6 = {"sd ddmmyy->set date\r\n",21}, \
MENU7 = {"\r\n",2}, \
MENU8 = {"\r\n",2};
void ShowMenu(void)
{
UartSendST(MAINM.item,MAINM.size);
UartSendST(MENU0.item,MENU0.size);
UartSendST(MENU1.item,MENU1.size);
UartSendST(MENU2.item,MENU2.size);
UartSendST(MENU3.item,MENU3.size);
UartSendST(MENU4.item,MENU4.size);
UartSendST(MENU5.item,MENU5.size);
UartSendST(MENU6.item,MENU6.size);
UartSendST(MENU7.item,MENU7.size);
UartSendST(MENU8.item,MENU8.size);
}
Ⅵ 51单片机的uart串口的TXD与RXD为什么必须是P3.0与P3.1口,P3.2与P3.3也能做TXD与RXD吗
你的想法很好,即使是小白的问题,也要分清是哪一类。想象力是创造力的翅膀,相信你的思维能力适合学习单片机,如果肯努力,将来会有很好的发展。
对于大多数51单片机而言,第二功能是由内核结构决定的,也就是说设计芯片时已经固定了,除非你用模拟的方法编写相应程序,否则必须那样使用。这也仅对串口有效,像WR\、RD\等你模拟都模拟不成。
之所以赞赏你的想象力,是因为已经有单片机厂商如此做了(单串口还是固定的,因为要ISP下载代码),C8051F单片机不分管脚是可以重新分配的。
Ⅶ 51单片机中UART通信中的公式中除2是什么意思
51单片机中UART通信中的公式中除2是又经过2倍分频了,这要结合串口电路原理就明白了。