NEC V850 之 串口通信(UART4)
这次的串口的程序还是把接收的字符再发送出去。之前先说明几点
本文引用地址://m.amcfsurvey.com/article/201612/325102.htm- 系统时钟,设置系统时钟输出脚输出,方便测量目前的系统时钟,有了准确的时钟才能计算波特率等信息。
- 波特率计算方式,根据寄存器UDnCTL1和UDnCTL2来计算,见下图
![](http://m.amcfsurvey.com/editerupload/fetch/20161101/325102_1_0.jpg)
举个例子:如果串口的总线时钟和系统时钟一致为32MHz,我们需要115200bps的波特率,下面算出UDnCTL2寄存器的值(即K值),可以得到一个方程为115200bps = 32MHz / 2*k ,可以求的 k = 138.888 ,取值138或者139。可见通信是有误差的。只要是误差量足够小就不足为虑,不要进行连续的大数据传输问题就不会很大。下面来计算下误差率,如果取值为138的话,则通信波特率可以由 32MHz / (2*138) = 115942.0289855072 bps ,误差率为((115942.02899/ 115200) - 1)* 100 = 0.644%。
下面是代码部分了
- 串口接收中断屏蔽寄存器 UD4RIC
- 串口控制寄存器0 UD4CTL0
- 串口控制寄存器1UD4CTL1
- 串口控制寄存器2 UD4CTL2
- 时钟选择控制寄存器3 SELCNT3 -- ISEL34
- 串口状态寄存器 UD4STR -- UD4TSF
- 串口发送数据寄存器 UD4TX
- 串口接收数据寄存器UD4RX
程序上操作:串口初始化,串口使能,串口禁止,串口查询发送一个字符,串口中断接收一个字符。
- 串口初始化
-
- 禁止串口发送,接受及运行;
- 关闭接收中断,清接收中断标志;
- 设置中断优先级;
- 设置串口波特率;
- 设置串口时钟;
- 设置串口数据帧属性;
- 设置串口RXD,TXD端口属性。
- 串口使能
-
- 使能串口接收中断,清接收中断标志位;
- 使能串口发送,接收及运行标志位。
- 串口禁止
-
- 禁止串口发送,接收及运行;
- 禁止串口的三种中断源。
- 串口查询发送一个字符
- 串口中断接收一个字符
下面是具体的代码了。
代码出处:main.c
#include
#include
#include "system.h"
#include "Uart.h"
void main( void )
{
SystemClkInit(); // 初始化系统时钟为32MHz
/* CLKOUT pin set */
PMCCM |= 0x02; // 设置系统时钟输出引脚使能,输出值为系统时钟(32MHz)
__DI(); // 关闭总中断
UARTD4_Init(); // 初始化串口4
__EI(); // 打开总中断
UARTD4_Start(); // 使能串口4应用
while (1)
{;}
}
代码出处:Uart.c
#include "Uart.h"
/*******************************************************************************
* Function Name : UARTD4_Init
* Description : 串口4初始化
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void UARTD4_Init( void )
{
UD4TXE = 0; /* disable transmission operation(uartd4) */
UD4RXE = 0; /* disable reception operation(uartd4) */
UD4PWR = 0; /* disable UARTD4 operation */
UD4RMK = 1; /* INTUD4Rinterruptdisable */
UD4RIF = 0; /* clear INTUD4R interrupt flag */
UD4RIC |= 0x07; // 设置接受中断优先级为最低优先级
UD4CTL1 = UARTD_BASECLK_FXP1_1; // 设置串口4的时钟为系统时钟32MHz,不分频
UD4CTL2 = 138; // 设置波特率为 115200 bps,计算公式见datasheet 573页
ISEL34 = 0; // 设置串口4的时钟选择为fXP1,见datasheet 220页
UD4CTL0 = UARTD_TRANSFDIR_LSB | UARTD_PARITY_NONE | UARTD_DATALENGTH_8BIT | UARTD_STOPLENGTH_1BIT;
// 设置数据帧格式为 从低位开始,无奇偶效验位,8位数据位,1位停止位
/* UARTD4 TXDD4(P915) pin set */ // 设置端口为第二功能模式,配置关系见datasheet 138页
PFC9H_bit.no7 = 1;
PFCE9H_bit.no7 = 1;
PMC9H_bit.no7 = 1;
/* UARTD4 RXDD4(P914) pin set */
PFC9H_bit.no6 = 1;
PFCE9H_bit.no6 = 1;
PMC9H_bit.no6 = 1;
}
/*******************************************************************************
* Function Name : UARTD4_Start
* Description : 串口4使能
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void UARTD4_Start( void )
{
UD4RIF = 0; /* clear INTUD4R interrupt flag */
UD4RMK = 0; /* INTUD4R interrupt enable */
UD4PWR = 1; /* enable UARTD4 operation */
UD4TXE = 1; /* enable transmission operation(uartd4) */
UD4RXE = 1; /* enable reception operation(uartd4) */
}
/*******************************************************************************
* Function Name : UARTD4_Stop
* Description : 串口4禁止
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void UARTD4_Stop( void )
{
UD4TXE = 0; /* disable transmission operation(uartd4) */
UD4RXE = 0; /* disable reception operation(uartd4) */
UD4PWR = 0; /* disable UARTD4 operation */
// 关闭3个中断源
UD4TMK = 1; /* INTUD4T interrupt disable */
UD4TIF = 0; /* clear INTUD4T interrupt flag */
UD4RMK = 1; /* INTUD4R interrupt disable */
UD4RIF = 0; /* clear INTUD4R interrupt flag */
UD4SMK = 1; /* INTUD4S interrupt disable */
UD4SIF = 0; /* clear INTUD4S interrupt flag */
}
/*******************************************************************************
* Function Name : UART4_SendChar
* Description : 串口4发送一个字符
* Input : 要发送的字符
* Output : None
* Return : None
*******************************************************************************/
void UART4_SendChar(unsigned char word)
{
if((UD4STR & 0x80) == 0)
{
UD4TX = word;
}
UD4TIF = 0; // 使用的是查询方式发送串口数据,但是相应标识为会置位,这里为了保存代码完整性
}
/*******************************************************************************
* Function Name : MD_INTUD4R
* Description : 接收中断服务函数
* Input : None
* Output : None
* Return : None
*******************************************************************************/
#pragma vector = INTUD4R_vector
__interrupt void MD_INTUD4R(void)
{
volatile unsigned char rx_data;
rx_data = UD4RX;
UART4_SendChar(rx_data);
UD4RIF = 0; // 串口接收来中断并没有置位寄存器,这里为了保持代码完整性
}
串口是难度并不很大,实验是可以成功的,但是最后还有2个问题没有搞清楚,一个是来接收中断的时候,相应的UD4RIF标志位没有置位,始终是低电平,还有就是查询发送的时候,发送中断使能是关闭的但是以发送完毕,对应的UD4TIF标志位就会置位。但是这两点都不影响串口的操作,不知道瑞萨是怎么考虑的,见下图:
![](http://m.amcfsurvey.com/editerupload/fetch/20161101/325102_1_1.jpg)
![](http://m.amcfsurvey.com/editerupload/fetch/20161101/325102_1_2.jpg)
评论