标签:自己 stat 串口 stm32 总结 event clockd enable 模式
前一段时间一直在研究modbus协议的源代码,并且自己用单片机C实现了一下但是其实没什么卵用的,因为根本就不可能用在实际工程中也是自己当时太不懂行情了上网搜了一下我觉得实际人家产品上用的很少应该是自己去写,因为那根本就不合算而且还会出错,又走了弯路我觉得一般的做从站用freemodbus就很好也是因为水平太菜就这个freemodbus也差不多弄了有1个礼拜今天终于搞定了能转起来并能正确的返回数据因此在这里总结一下:void
ExitCriticalSection( )
{
__ASM volatile("cpsie i");
}
把关键的代码贴出来我觉得把这几项弄清楚应该就没什么问题了:
void main(void)
{
NVIC_Configuration();
eMBInit(MB_RTU, 1, 0, 9600, MB_PAR_NONE);
eMBEnable();
while(1)
{
(void)eMBPoll();
}
}
主函数这套了就比较套路了在官网上就是这么给的也没什么说的。下面我就按照协议的调用流程来贴出来了
串口初始化函数:
void uart_init(u32 bound)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//USART1_RX PA.10
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = bound;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
USART_Cmd(USART1, ENABLE);
}
这个也比较常规了
事件初始化函数
static eMBEventType eQueuedEvent;
static BOOL xEventInQueue;
BOOL
xMBPortEventInit( void )
{
xEventInQueue = FALSE;
return TRUE;
}
时间初始化函数
BOOL
xMBPortTimersInit( USHORT usTim1Timerout50us )
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
TIM_TimeBaseStructure.TIM_Period = 50;
TIM_TimeBaseStructure.TIM_Prescaler = (7200 - 1);
TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
TIM_Cmd(TIM2, ENABLE);
return TRUE;
}
还有两个时间的函数也比较简单
void
vMBPortTimersEnable( )
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
TIM_SetCounter(TIM2, 0);
//TIM_Cmd(TIM2, ENABLE);
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
}
void
vMBPortTimersDisable( )
{
TIM_SetCounter(TIM2, 0);
//TIM_Cmd(TIM2, DISABLE);
TIM_ITConfig(TIM2, TIM_IT_Update, DISABLE);
}
把串口中断和时钟中断的函数也贴出来
void USART1_IRQHandler(void)
{
//static unsigned int u;
//u++;
if(USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
{
prvvUARTRxISR();
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
//printf("u=%u\r\n",u);
}
if(USART_GetITStatus(USART1, USART_IT_TXE) == SET)
{
//printf("com in ittxe intrupt\r\n");
prvvUARTTxReadyISR();
//USART_ClearITPendingBit(USART1, USART_IT_TC);
}
}
void TIM2_IRQHandler(void)
{
//static unsigned int t;
//t++;
//printf("t=%u",t);
TIMERExpiredISR();
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
}
还有就是事件的请求和发送函数
BOOL
xMBPortEventPost( eMBEventType eEvent )
{
xEventInQueue = TRUE;
eQueuedEvent = eEvent;
return TRUE;
}
BOOL
xMBPortEventGet( eMBEventType * eEvent )
{
BOOL xEventHappened = FALSE;
if( xEventInQueue )
{
*eEvent = eQueuedEvent;
xEventInQueue = FALSE;
xEventHappened = TRUE;
}
return xEventHappened;
}
这样应该就没什么大问题了,仔细点,在多分析协议源码多花点时间就肯定没有什么问题解决不了。****
标签:自己 stat 串口 stm32 总结 event clockd enable 模式
原文地址:http://blog.51cto.com/13638458/2308626