本帖最后由 gjianw217 于 2016-10-5 13:08 编辑
本帖子将实现如下功能:MCU通过串口1和上位机对话,MCU在收到上位机发过来的字符串(以回车换行结束)后,原原本本的返回给上位机。下载后,DS0闪烁,提示程序在运行,同时每隔一定时间,通过串口1输出一段信息到电脑。
1 MM32103串口
串口作为 MCU 的重要外部接口,同时也是软件开发重要的调试手段,其重要性不言而喻。现在基本上所有的 MCU 都会带有串口,MM32F103自然也不例外。MM32F103上共有3个串口模块,而在开发板使用了UART1,并通过CH340将其转换成USB接口与上位机进行通信。
串口最基本的设置
(1)串口时钟使能。串口作为
MM32F103的一个外设 ,其时钟由外设时钟使能寄存器控制,这里使用的是串口1是在APB2ENR寄存器的第 14 位。
(2)串口复位。当外设出现异常的时候,可以通过寄存器里面对应置,实现该外设的复位,然后重新配置这个外设达到让其工作目的。一般在系统刚开始配置外设的时候都会先执行复位该外设操作。串口 1的复位是通过配置 APB2RSTR寄存器的第 14 位来实现 的。
(3)串口波特率设置。每个串口都有一自己独立的波特率寄存器 UART_BRR,通过设置该寄存器 ,就可以达到配置不同波特率的目的。
(4)串口控制。MM32F103的串口控制寄存器分为两种
,一种是中断相关的,一种是控制相关的
1)中断相关寄存器
2)控制相关寄存器
(5)数据发送与接收。MM32F103的发送与接收是通过数据寄存器UART_TDR 和 UART_RDR 。各位描述如图所示:
(6)串口状态。串口的状态可以通过寄存器 USART_CSR读取。 USART_CSR的各位描述如下图所示:
2 硬件电路
3 代码实现
(1)初始化操作
void uart_init(u32 pclk2,u32 bound)
{
u32 tempBaud;
//-------------------------------------------------
RCC->APB2ENR|=1<<2; //enable the PORTA clock
RCC->APB2ENR|=1<<14; //enable the UART1 clock
GPIOA->CRH&=0XFFFFF00F; //IO status setting
GPIOA->CRH|=0X000008B0; //IO status setting
RCC->APB2RSTR|=1<<14; //reset the uart1
RCC->APB2RSTR&=~(1<<14);//stop the uart1 reset
//-------------------------------------------------
/* Determine the uart_baud*/
tempBaud = (pclk2*1000000 / 16) /(bound);
/* Write to UART BRR */
UART1->BRR = tempBaud;
UART1->CCR|=0X30; //config the uart parament
//-------------------------------------------------
#if EN_UART1_RX
UART1->GCR = 0X19;
UART1->IER = 0X2;
UART1->ICR = 0X2; //
MY_NVIC_Init(3,3,UART1_IRQn,2);//
#endif
}
(2)中断函数
void UART1_IRQHandler(void)
{
u8 res;
if((UART1->ISR & UART_IT_RXIEN) != (uint16_t)RESET) //recv the data
{
res=(uint16_t)(UART1->RDR & (uint16_t)0x00FF);
UART1->ICR |= 2; //clear the recv interrupt mark
if((UART_RX_STA&0x8000)==0) //recv not completely
{
if(UART_RX_STA&0x4000) //recv the 0x0d(enter)
{
if(res!=0x0a)UART_RX_STA=0; //recv the error and restart to recv
else UART_RX_STA|=0x8000; //recv completely
}else //recv not 0x0d
{
if(res==0x0d)UART_RX_STA|=0x4000;
else
{
UART_RX_BUF=res;
UART_RX_STA++;
if(UART_RX_STA>(UART_REC_LEN-1))UART_RX_STA=0;//recv data error
}
}
}
}
}
(3)主函数
int main(void)
{
//initilization
u8 t;
u8 len;
u16 times=0;
delay_init(72);
uart_init(72,9600); //baudrate 9600
LED_Init();
while(1)
{
if(UART_RX_STA&0x8000)
{
len=UART_RX_STA&0x3fff;// data length
printf("\r\n您发送的消息为:\r\n");
for(t=0;tCSR&UART_IT_TXIEN)==0);/waiting to send all the recv data
UART1->TDR=UART_RX_BUF;
}
printf("\r\n\r\n");
UART_RX_STA=0;
}else
{
times++;
if(times%5000==0)
{
printf("\r\n串口实验:\r\n");
}
if(times%200==0)printf("\r请输入数据,以回车键结束\n");
if(times%30==0)LED0=!LED0;
delay_ms(10);
}
}
}
4 实验效果
本帖最后由 gjianw217 于 2016-10-5 13:08 编辑
本帖子将实现如下功能:MCU通过串口1和上位机对话,MCU在收到上位机发过来的字符串(以回车换行结束)后,原原本本的返回给上位机。下载后,DS0闪烁,提示程序在运行,同时每隔一定时间,通过串口1输出一段信息到电脑。
1 MM32103串口
串口作为 MCU 的重要外部接口,同时也是软件开发重要的调试手段,其重要性不言而喻。现在基本上所有的 MCU 都会带有串口,MM32F103自然也不例外。MM32F103上共有3个串口模块,而在开发板使用了UART1,并通过CH340将其转换成USB接口与上位机进行通信。
串口最基本的设置
(1)串口时钟使能。串口作为
MM32F103的一个外设 ,其时钟由外设时钟使能寄存器控制,这里使用的是串口1是在APB2ENR寄存器的第 14 位。
(2)串口复位。当外设出现异常的时候,可以通过寄存器里面对应置,实现该外设的复位,然后重新配置这个外设达到让其工作目的。一般在系统刚开始配置外设的时候都会先执行复位该外设操作。串口 1的复位是通过配置 APB2RSTR寄存器的第 14 位来实现 的。
(3)串口波特率设置。每个串口都有一自己独立的波特率寄存器 UART_BRR,通过设置该寄存器 ,就可以达到配置不同波特率的目的。
(4)串口控制。MM32F103的串口控制寄存器分为两种
,一种是中断相关的,一种是控制相关的
1)中断相关寄存器
2)控制相关寄存器
(5)数据发送与接收。MM32F103的发送与接收是通过数据寄存器UART_TDR 和 UART_RDR 。各位描述如图所示:
(6)串口状态。串口的状态可以通过寄存器 USART_CSR读取。 USART_CSR的各位描述如下图所示:
2 硬件电路
3 代码实现
(1)初始化操作
void uart_init(u32 pclk2,u32 bound)
{
u32 tempBaud;
//-------------------------------------------------
RCC->APB2ENR|=1<<2; //enable the PORTA clock
RCC->APB2ENR|=1<<14; //enable the UART1 clock
GPIOA->CRH&=0XFFFFF00F; //IO status setting
GPIOA->CRH|=0X000008B0; //IO status setting
RCC->APB2RSTR|=1<<14; //reset the uart1
RCC->APB2RSTR&=~(1<<14);//stop the uart1 reset
//-------------------------------------------------
/* Determine the uart_baud*/
tempBaud = (pclk2*1000000 / 16) /(bound);
/* Write to UART BRR */
UART1->BRR = tempBaud;
UART1->CCR|=0X30; //config the uart parament
//-------------------------------------------------
#if EN_UART1_RX
UART1->GCR = 0X19;
UART1->IER = 0X2;
UART1->ICR = 0X2; //
MY_NVIC_Init(3,3,UART1_IRQn,2);//
#endif
}
(2)中断函数
void UART1_IRQHandler(void)
{
u8 res;
if((UART1->ISR & UART_IT_RXIEN) != (uint16_t)RESET) //recv the data
{
res=(uint16_t)(UART1->RDR & (uint16_t)0x00FF);
UART1->ICR |= 2; //clear the recv interrupt mark
if((UART_RX_STA&0x8000)==0) //recv not completely
{
if(UART_RX_STA&0x4000) //recv the 0x0d(enter)
{
if(res!=0x0a)UART_RX_STA=0; //recv the error and restart to recv
else UART_RX_STA|=0x8000; //recv completely
}else //recv not 0x0d
{
if(res==0x0d)UART_RX_STA|=0x4000;
else
{
UART_RX_BUF=res;
UART_RX_STA++;
if(UART_RX_STA>(UART_REC_LEN-1))UART_RX_STA=0;//recv data error
}
}
}
}
}
(3)主函数
int main(void)
{
//initilization
u8 t;
u8 len;
u16 times=0;
delay_init(72);
uart_init(72,9600); //baudrate 9600
LED_Init();
while(1)
{
if(UART_RX_STA&0x8000)
{
len=UART_RX_STA&0x3fff;// data length
printf("\r\n您发送的消息为:\r\n");
for(t=0;tCSR&UART_IT_TXIEN)==0);/waiting to send all the recv data
UART1->TDR=UART_RX_BUF;
}
printf("\r\n\r\n");
UART_RX_STA=0;
}else
{
times++;
if(times%5000==0)
{
printf("\r\n串口实验:\r\n");
}
if(times%200==0)printf("\r请输入数据,以回车键结束\n");
if(times%30==0)LED0=!LED0;
delay_ms(10);
}
}
}
4 实验效果