你好!欢迎来到深圳市颖特新科技有限公司!
语言
当前位置:首页 >> MM32/灵动微电子 >> MM32SPIN2x 电机专用MCU功能特色——UART模块Bit9功能

MM32SPIN2x 电机专用MCU功能特色——UART模块Bit9功能

关键字:电机MCU 灵动微 作者: 来源: 发布时间:2018-12-27  浏览:64

上一章节中已经教大家如何使用MM32SPIN2x的比较器轮询功能,本章节将与大家一起配置UART的Bit9模式实现多机通讯功能。

图1UART多机通信

在双机通讯中,UART的8bit通信的第九位一般是奇偶校验位,而多机通讯中,第九位用于标识地址或数据,常用1表示后面的是从机地址,0表示后面的是数据。我们通常希望只有被寻址的接收者才被激活,来接收随后的数据,这样就可以减少由未被寻址的接收器的参与带来的多余的UART服务开销。未被寻址的设备可启用其静默功能置于静默模式。在静默模式里,任何接收状态位都不会被设置,所有接收中断被禁止。

图2UART多机通信

通过 UART 可以实现多处理器通信 (将几个 UART 连在一个网络里)。例如某个 UART 设备可以是主,它的 TX 输出和其他 UART 从设备的 RX 输入相连接; UART 从设备各自的TX 输出逻辑地与在一起,并且和主设备的 RX 输入相连接。

在多处理器配置中,我们通常希望只有被寻址的接收者才被激活,来接收随后的数据,这样就可以减少由未被寻址的接收器的参与带来的多余的 UART 服务开销。

未被寻址的设备可启用其静默功能置于静默模式。在静默模式里:

• 任何接收状态位都不会被设置。

• 所有接收中断被禁止。

• UART_CCR 寄存器中的 RWU 位被置 1。 RWU 可以被硬件自动控制或在某个条件下由软件写入。

根据 UART_CCR 寄存器中的 WAKE 位状态, UART 可以用二种方法进入或退出静默模式。

• 如果 WAKE 位被复位:进行空闲总线检测。

• 如果 WAKE 位被设置:进行地址标记检测。

今天与大家一起学习如何配置使用MM32SPIN2x的UART的Bit9模式实现多机通讯功能。

在使能UART_CCR寄存器的B8EN控制位后,UART就会使能9位数据的发送和接收,可以发送和接收9位数据。注意:在 B8EN 使能后,奇偶校验使能位PEN不起作用。

数据发送的时候,在写入数据到发送寄存器UART_TDR前,需要先设置B8TXD。B8TXD作为发送数据的MSB和UART_TDR的值同时发送。如果设置了B8TOG,如果B8TXD与B8POL相同时,表示该数据作为地址帧或者同步帧,发送结束后B8TXD会自动翻转。在接下来的数据发送过程中,不需要再设置B8TXD为无效电平。

数据接收的时候,接收数据的最高位可以从寄存器位B8RXD读到。如果接收的B8RXD与B8POL相同时,中断状态寄存器UART_ISR的RXB8_INTF位会置位。

UART9Bit模式的配置步骤如下:

1) 串口时钟使能,GPIO时钟使能

2) 串口复位

3) GPIO端口模式设置

4) 串口参数初始化

5)9Bit参数配置

5) 开启中断并且初始化NVIC(可选)

6) 使能串口

7) 编写中断处理函数

程序中配置如下:

voidUart_9Bit_ConfigInit(u32 bound)

{

GPIO_InitTypeDefGPIO_InitStructure;

UART_InitTypeDefUART_InitStructure;

NVIC_InitTypeDefNVIC_InitStruct;



//时钟使能

RCC_APB2PeriphClockCmd(RCC_APB2Periph_UART1,ENABLE);

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,ENABLE);



//串口复位及参数初始化

UART_DeInit(UART1);

UART_InitStructure.UART_BaudRate= bound;

UART_InitStructure.UART_WordLength= UART_WordLength_8b;

UART_InitStructure.UART_StopBits= UART_StopBits_1;

UART_InitStructure.UART_Parity= UART_Parity_No;

UART_InitStructure.UART_HardwareFlowControl=UART_HardwareFlowControl_None;

UART_InitStructure.UART_Mode= UART_Mode_Rx | UART_Mode_Tx;

UART_Init(UART1,&UART_InitStructure);



//开启中断并初始化

UART_ClearITPendingBit( UART1, UART_IT_RXIEN);

UART_ITConfig(UART1, UART_IT_RXIEN, ENABLE );



NVIC_InitStruct.NVIC_IRQChannel= UART1_IRQn;

NVIC_InitStruct.NVIC_IRQChannelCmd= ENABLE;

NVIC_InitStruct.NVIC_IRQChannelPriority= 0;

NVIC_Init(&NVIC_InitStruct);



//GPIO端口配置

GPIO_PinAFConfig(GPIOA,GPIO_PinSource9, GPIO_AF_1);

GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_1);



GPIO_InitStructure.GPIO_Pin= GPIO_Pin_9;

GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AF_PP;

GPIO_Init(GPIOA,&GPIO_InitStructure);



GPIO_InitStructure.GPIO_Pin= GPIO_Pin_10;

GPIO_InitStructure.GPIO_Mode= GPIO_Mode_IN_FLOATING;

GPIO_Init(GPIOA,&GPIO_InitStructure);



//UART 9Bit参数配置

UART_Enable9bit(UART1,ENABLE);//UART9bit使能控制位

UART_Set9bitPolarity(UART1,UART_9bit_Polarity_High); //第九位高电平有效

UART_WakeUpConfig(UART1,UART_WakeUp_AddressMark);//地址标记唤醒

UART_ReceiverWakeUpCmd(UART1,ENABLE);//静默模式启用,从机配置静默模式,如果作为主机,需要将该句disable

UART_SetRXMASK(UART1,0xFF);//启用8位地址匹配

UART_SetRXAddress(UART1,0x5A);//地址设置为0x5A

UART_ITConfig(UART1, UART_IT_RXB8, ENABLE ); //开启地址帧帧中断



//使能串口

UART_Cmd(UART1,ENABLE);

}



在上述配置中,我们启用了地址标记唤醒,在接收到的地址帧中的地址与UART_RXADDR中的地址匹配时,UART_CCR中的RWU位由系统清零,从静默模式中唤醒,同时置位UART_ISR的RXB8_INTF和RX_INTF位;若地址不匹配,则只有UART_ISR的RXB8_INTF被置位,UART进入静默模式。



在库函数中还有两个在发送时会用到的函数:

void UART_Set9bitAutomaticToggle(UART_TypeDef*UARTx, FunctionalState NewState);

//B8TOG设置,在地址帧发送结束后,B8TXD自动翻转翻转,进入数据帧格式

voidUART_Set9bitLevel(UART_TypeDef* UARTx, FunctionalState NewState);

//B8TXD设置,用于设置下一帧是地址帧还是数据帧



在主机与从机简单配置之后,我们用简单的数据测试配置的功能:



主机程序:

void UART1_9B_TX(u8addr,u8*str,u16 len)

{

UART_Set9bitLevel(UART1,ENABLE); //下一个字节为地址字节

UartSendByte(addr); //地址

UartSendGroup(str,len); //自动翻转为数据字节,发送str

}



intmain(void)

{

InitSystick();//systick初始化,方便调试

Uart_ConfigInit(9600);



UART1_9B_TX(0x52,"123",3); //向地址0x52发送0x31 0x32 0x33

UART1_9B_TX(0x5A,"456",3); //向地址0x5A发送0x34 0x35 0x36

UART1_9B_TX(0x53,"789",3); //向地址0x53发送0x37 0x38 0x39

while(1){ }

}



从机程序:

intmain(void)

{

InitSystick();//systick初始化,方便调试

Uart_ConfigInit(9600);

while(1){ } //等待接收数据

}



voidUART1_IRQHandler(void) //中断处理函数

{

if(UART_GetITStatus(UART1, UART_IT_RXB8) )

{

UART_ClearITPendingBit(UART1, UART_IT_RXB8); //清除中断标志位

UART_ClearITPendingBit(UART1, UART_IT_RXIEN); //清除中断标志位,不接受地址字节数据

}

if(UART_GetITStatus(UART1, UART_IT_RXIEN) )

{

UART_ClearITPendingBit( UART1, UART_IT_RXIEN); //清除中断标志位

uartTXbuf[uartTXlen ++ ] = UART_ReceiveData(UART1);//接收数据

UartSendByte(UART_ReceiveData(UART1));

}

}

主机发送的数据:0x152(地址) 0x031 0x0320x033 0x15A(地址) 0x0340x035 0x036 0x153(地址) 0x0370x038 0x039

从机将接收到的数据帧经UART再进行转发。


图3 测试结果

可以看到,从机在收到地址帧后,从机只在接收到0x15A之后从静默模式切换回正常模式,接下来的数据会接收并触发接收中断,将接收到的0x34 0x350x36再发回主机,在接收到0x152和0x153这两个不匹配的地址后保持或切换到静默模式,不再接收数据。

编辑:admin  最后修改时间:2023-03-22

联系方式

0755-82591179

传真:0755-82591176

邮箱:vicky@yingtexin.net

地址:深圳市龙华区民治街道民治大道973万众润丰创业园A栋2楼A08

Copyright © 2014-2023 颖特新科技有限公司 All Rights Reserved.  粤ICP备14043402号-4