C8051F340学习笔记UART.docx
《C8051F340学习笔记UART.docx》由会员分享,可在线阅读,更多相关《C8051F340学习笔记UART.docx(16页珍藏版)》请在冰豆网上搜索。
C8051F340学习笔记UART
C8051F340串口学习笔记
UART0是一个异步、全双工串口,它提供标准8051串行口的方
式1和方式3。
UART0具有增强的波特率发生器电路,有多个时钟
源可用于产生标准波特率。
接收数据缓冲机制允许UART0在软件尚未读取前一个数据字节的情况下开始接收第二个输入数据字节。
UART0有两个相关的特殊功能寄存器:
串行控制寄存器(SCON0)
和串行数据缓冲器(SBUF0)。
写SBUF0时自动访问发送寄存器;读
SBUF0时自动访问接收寄存器,不可能从发送数据寄存器中读数据。
如果UART0中断被允许,则每次发送完成TI0位被置‘1’或接收到数据字节RI0位被置‘1’时将产生中断。
当CPU转向中断服务程序时硬件不清除UART0中断标志。
中断标志必须用软件清除。
UART0波特率由定时器1工作在8位自动重装载方式产生,定
时器1应被配置为方式2,即8位自动重装载方式,定时器1的时钟可以在6个时钟源中选择:
SYSCLK、SYSCLK/4、SYSCLK/12、SYSCLK/48、外部振荡器时钟/8和外部输入T1。
其中T1CLK是定时器1的时钟频率,T1H是定时器1的高字节(重载值)UART0提供标准的异步、全双工通信,其工作方式(8位或9位)通过S0MODE来选择
8位UART
每个数据字节共使用10位:
一个起始位、8个数据位(LSB在先)
和一个停止位,软件向SBUF0寄存器写入一个字节时开始数据发送。
在发送结束时中断标志TI0被置
1
UART1(仅C8051F340/14/5有)
UART1的使用与UART0基本大致相同,但是。
UART1包含一个由16
位定时器和可编程预分频器构成的专用波特率发生器,能产生很宽围
的波特率,有多个时钟源可用于产生标准波特率。
UART1有六个相关的特殊功能寄存器。
三个用于波特率发生器
(SBCON1、SBRLH1和SBRLL1),两个用于数据格式、控制和状态功能(SCON1和SMOD1),一个用于发送和接收数据(SBUF1)。
使用UART1时,波特率发生器必须被使能。
寄存器SBRLH1和SBRLL1保持该专用定时器的16位重载值,对于可靠的UART操作,建议不要将UART波特率配置为大于SYSCLK/16。
C8051F330
串口
UART0
示例程序
//使用F340,串口为P0.4(TX0),P0.5(RX0);
#include
#include
#defineSYSCLK24500000//系统工作频率
#defineBAUDRATE9600//串口工作波特率
//-----------------------------------------------------------------------------
//功能函数
//-----------------------------------------------------------------------------
voidSYSCLK_Init(void);
voidPORT_Init(void);
voidUART0_Init(void);
voidUart0_Transmit(unsignedchartmp);
voidsendstr(unsignedchar*tmp);
unsignedchartemp;
voiddelay_1ms()
{
unsignedintj;
for(j=3060;j>0;j--);
}
voiddelay_ms(unsignedinti)
{
for(;i>0;i--)delay_1ms();
}
//-----------------------------------------------------------------------------
//主程序
//-----------------------------------------------------------------------------
voidmain(void)
{
PCA0MD&=~0x40;
//禁止看门狗
PORT_Init();
SYSCLK_Init();
UART0_Init();
//初始化端口I/O
//初始化系统时钟
//串口初始化
EA=1;
ES0=1;
while
(1)
{
delay_ms(1000);
sendstr("WelcometoJuly'sHut!
\n");
Uart0_Transmit(032);//发送空格
}
}
//-----------------------------------------------------------------------------
//端口初始化
//-----------------------------------------------------------------------------
voidPORT_Init(void)
{
P0MDOUT|=0x10;
XBR0=0x01;
XBR1=0x40;
//使能UTX为推挽输出
//使能UART0占用P0.4(TXD)
//使能交叉开关
和
P0.5(RXD)
XBR2=0x00;
//禁止
UART1
}
//-----------------------------------------------------------------------------
//系统时钟初始化
//-----------------------------------------------------------------------------
voidSYSCLK_Init(void)
{
OSCICN|=0x03;
RSTSRC=0x04;
//配置部振荡器的的最大频率
//
}
//-----------------------------------------------------------------------------
//串口UART0初始化
//-----------------------------------------------------------------------------
voidUART0_Init(void)
{
SCON0=0x10;
if(SYSCLK/BAUDRATE/2/256<1)
{
TH1=-(SYSCLK/BAUDRATE/2);
CKCON&=~0x0B;
CKCON|=0x08;
}
elseif(SYSCLK/BAUDRATE/2/256<4)
{
TH1=-(SYSCLK/BAUDRATE/2/4);
CKCON&=~0x0B;
CKCON|=0x09;
}
elseif(SYSCLK/BAUDRATE/2/256<12)
{
TH1=-(SYSCLK/BAUDRATE/2/12);
CKCON&=~0x0B;
}
else
{
TH1=-(SYSCLK/BAUDRATE/2/48);
CKCON&=~0x0B;
CKCON|=0x02;
}
TL1=TH1;
TMOD&=~0xf0;
TMOD|=0x20;
TR1=1;
//TI0=1;
}
//-----------------------------------------------------------
//串口UART0中断
//-----------------------------------------------------------
//中断向量0x0023
voidUATR0_ISR(void)interrupt4
{
//Rx、Tx共用中断
//接收中断
if(!
TI0)
{
RI0=0;
temp=SBUF0;
Uart0_Transmit(temp);
}
//发送中断
elseTI0=0;
}
//-----------------------------------------------------------
//串口UART0发送
//-----------------------------------------------------------
voidUart0_Transmit(unsignedchartmp)
{
ES0=0;
//关
UART0
中断
EA=0;
//关全局中断
SBUF0=tmp;
while(TI0==0);
TI0=0;
ES0=1;
//开
UART0
中断
EA=1;
//开全局中断
}
//-----------------------------------------------------------
//发送字符串
//-----------------------------------------------------------
voidsendstr(unsignedchar*tmp)
{
while(*tmp)
{
Uart0_Transmit(*tmp++);
}
}
本程序是通过F340的uart0与PC进行串口通讯的例程,具体实现为当F340收到从PC传来的数据后将数据原样回发给PC机,端口为RX=P0.5,TX=P0.4#include
#defineucharunsignedchar
#defineuintunsignedint
/*****************************************************************
*端口初始化函数
*****************************************************************/
voidPORT_Init(void)
{
XBR0
=0x01;//I/O交叉开关寄存器0,UARTTX0,RX0
连到端口引脚
P0.4和P0.5
XBR1
=0x40;
//端口交叉开关使能
P0MDOUT=0x10;
//P0.4为推挽输出,其他的为漏极开路输出
}
/****************************************************************
*UART0初始化函数
*****************************************************************/
voidUART0_Init(void)
{
SCON0
|=0x10;
//方式0,8位的uart接,收允许
CKCON
=0x01;
//CKCON是时钟控制寄存器
TH1
=0x64;
//波特率为9600
TL1
=TH1;
TMOD
=0x20;
TR1
=1;
//定时器1运行控制,定时器1允许
TI0
=1;
//中断1类型选择,INT1为边沿触发
}
/*****************************************************************
*主函数
*****************************************************************/
voidmain()
{
charg;
PCA0MD&=~0x40;//关闭看门狗
OSCICN|=0x03;//P126部高频振荡器控制寄存器停止运行PORT_Init();//端口初始化
UART0_Init();//UART0初始化
while
(1)
{
while(RI0==0);//接收
g=SBUF0;
RI0=0;//手动清零
if(g!
='\0')
{
SBUF0=g;
while(TI0==0);//发送
TI0=0;
g='\0';
}
}
}
另外附送发送和接受子函数
voidSendchar(unsignedcharx)//发送字符的子函数
{TI0=0;SBUF0=x;
while(TI0==0);//发送
}
voidGetchar()
{RI0==0;buffer=SBUF0;
while(RI0==0);//接收//接收字符的子函数
}
voidsendstr(unsignedchar*tmp)//发送字符串的子函数
{
while(*tmp)
{
Uart0_Transmit(*tmp++);
}
}
注:
本程序全部来自于互联网,非本人所写,严禁用于商业用途,本人不承担法律责任
下面说一下本人经常使用的C8051F340端口、时钟、计数器、串口等配置的软件及方法使
用ConfigurationWizard进行串口的配置
1、选择C8051F340这个单片机,再依次选择—外设—串口进入以下界面
我们配置串口0,选择8位,Enable串口接收,再配置串口中断
下面是我配置好的串口子程序时钟选用外部时钟11。
0592MHz,UART0工作在8
位模式,8定时器自动重载,波特率,38400,并且使能串口中断,若上拉禁止
#include"C8051F340.h"
//Peripheralspecificinitializationfunctions,
//CalledfromtheInit_Device()functionvoidTimer_Init()
{
TMOD
=0x20;
CKCON
=0x08;
TH1
=0x70;
}
voidUART_Init()
{
SCON0
=0x10;
}
voidPort_IO_Init()
{
//P0.0
-
Unassigned,
Open-Drain,Digital
//P0.1
-
Unassigned,
Open-Drain,Digital
//P0.2
-
Unassigned,
Open-Drain,Digital
//P0.3
-
Unassigned,
Open-Drain,Digital
//P0.4
-
TX0(UART0),Open-Drain,Digital
//P0.5
-
RX0(UART0),Open-Drain,Digital
//P0.6
-
Skipped,
Push-Pull,
Analog
//P0.7
-
Skipped,
Push-Pull,
Analog
//P1.0
-
Unassigned,
Open-Drain,Digital
//P1.1
-
Unassigned,
Open-Drain,Digital
//P1.2
-
Unassigned,
Open-Drain,Digital
//P1.3
-
Unassigned,
Open-Drain,Digital
//P1.4
-
Unassigned,
Open-Drain,Digital
//P1.5
-
Unassigned,
Open-Drain,Digital
//P1.6
-
Unassigned,
Open-Drain,Digital
//P1.7
-
Unassigned,
Open-Drain,Digital
//P2.0
-
Unassigned,
Open-Drain,Digital
//P2.1
-
Unassigned,
Open-Drain,Digital
//P2.2
-
Unassigned,
Open-Drain,Digital
//P2.3
-
Unassigned,
Open-Drain,Digital
//P2.4
-
Unassigned,
Open-Drain,Digital
//P2.5
-
Unassigned,
Open-Drain,Digital
//P2.6
-
Unassigned,
Open-Drain,Digital
//P2.7
-
Unassigned,
Open-Drain,Digital
//P3.0
-
Unassigned,
Open-Drain,Digital
//P3.1
-
Unassigned,
Open-Drain,Digital
//P3.2
-
Unassigned,
Open-Drain,Digital
//P3.3
-
Unassigned,
Open-Drain,Digital
//P3.4
-
Unassigned,
Open-Drain,Digital
//P3.5
-
Unassigned,
Open-Drain,Digital
//P3.6
-
Unassigned,
Open-Drain,Digital
//P3.7
-
Unassigned,
Open-Drain,Digital
P0MDIN
=0x3F;
P0MDOUT
=0xC0;
P0SKIP
XBR0
XBR1
=0xC0;
=0x01;
=0xC0;
}
voidOscillator_Init()
{
//使用外部晶振对其进行初始化
inti=0;
OSCXCN=0x67;
for(i=0;i<3000;i++);//Wait1msforinitialization
while((OSCXCN&0x80)==0);
CLKSEL=0x01;
OSCICN=0x00;
}
voidInterrupts_Init()
{
IE
=0x90;
}
//Initializationfunctionfordevice,
//CallInit_Device()fromyourmainprogramvoidInit_Device(void)
{
Timer_Init();UART_Init();Port_IO_Init();Oscillator_Init();Interrupts_Init();
}