新手入门
- 积分
- 17
- 金钱
- 17
- 注册时间
- 2019-1-26
- 在线时间
- 13 小时
|
发表于 2019-1-26 16:29:52
|
显示全部楼层
八度大神 新人小白 第一次接触到modbus 按照你的移植步骤移植以后发送0A 04 00 01 00 01 61 71 串口助手如图,也不知道问题出在哪了 好像是串口中断函数中的清中断有问题 也不知道怎么修改 ,还请不吝赐教
void
vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable )
{
/* If xRXEnable enable serial receive interrupts. If xTxENable enable
* transmitter empty interrupts.
*/
if (xRxEnable) //接收使能
{
USART3->CR1 |=(1<<5); //使能接收中断
}
else //失能
{
USART3->CR1 &=~(1<<5); //失能接收中断
}
if (xTxEnable) //发送使能
{
USART3->CR1 |=(1<<7); //使能
}
else //失能
{
USART3->CR1 &=~(1<<7); //使能
}
}
BOOL
xMBPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits, eMBParity eParity )
{
(void)ucPORT; //不修改串口号
(void)ucDataBits; //不修改数据位长度
(void)eParity; //不修改检验格式
u8 over; //过采样率
float USARTDIV; //小数波特率
u32 DIV_Mantissa; //小数波特率整数部分
u32 DIV_Fraction; //小数波特率小数部分
/************IO的配置 PB10 PB11 复用为USART3的功能************/
//打开USART3的时钟
RCC->APB1ENR|=(0x1<<18);
//打开GPIOB时钟
RCC->AHB1ENR |=(1<<1);
//模式寄存器选择复用功能
GPIOB->MODER &=~(0xf<<20);
GPIOB->MODER |=(0xa<<20);
//选择具体的复用功能 都复用成USART3
GPIOB->AFR[1] &=~(0xff<<8);//清零
GPIOB->AFR[1] |=(0x77<<8);//复用为USART3功能
//打开串口使能
USART3->CR1 |=(1<<13);
//奇偶校验的选择(不使用)
USART3->CR1 &=~(1<<10);
//断路字符 不发送
USART3->CR1 &=~(1<<0);
//发送器使能
USART3->CR1 |=(1<<3);
//接收器使能
USART3->CR1 |=(1<<2);
/*****************小数波特率设置**********************/
#ifdef USART3_OVER8 //采用16倍采样
USART3->CR1 &=~(1<<15);
over=0;
#else //采用8倍采样
USART1->CR1 |=(1<<15);
over=1;
#endif
USARTDIV=(float)42000000/(ulBaudRate*8*(2-over));
DIV_Mantissa=USARTDIV;
DIV_Fraction=(USARTDIV-DIV_Mantissa)*8*(2-over);
//写入小数波特率寄存器中
USART3->BRR=(DIV_Mantissa<<4|DIV_Fraction);
/******************USART3中断************************/
//打开接收中断
USART3->CR1 |=(1<<5);
//打开发送中断
USART3->CR1 |=(1<<7);
//设置优先级
my_nvic_init(7-2, 0, 0, USART3_IRQn);
return FALSE;
}
BOOL
xMBPortSerialPutByte( CHAR ucByte )
{
//等待数据发送完成
while((USART3->SR &(1<<6))==0){;}
USART3->DR=ucByte;
return TRUE;
}
BOOL
xMBPortSerialGetByte( CHAR * pucByte )
{
//等待数据接受完成 SR 5位 如果改为 为 0 数据没有接收到 一直等待数据接收
while((USART3->SR &(1<<5))==0){;}
*pucByte=USART3->DR;
return TRUE;
}
//USART3中断服务函数
void USART3_IRQHandler(void)
{
if(USART3->SR&(1<<5))//接收中断
{
u8 data;
prvvUARTRxISR();
//清中断
data=USART3->DR;
}
if(USART3->SR&(1<<7))//发送中断
{
prvvUARTTxReadyISR();
//清中断
USART3->DR=0x0000;
}
}
/* ----------------------- Start implementation -----------------------------*/
BOOL
xMBPortTimersInit( USHORT usTim1Timerout50us )
{
uint16_t psc = 0;
psc = (uint16_t)((SystemCoreClock / 20000) - 1);
//1.打开TIM4时钟
RCC->APB1ENR |=(0x1<<2);
//2.选择内部时钟
TIM4->SMCR &=~(0x7<<0);
//3.选择分频值
TIM4->SC =psc-1;
//4.写入自动重装载值
TIM4->ARR =usTim1Timerout50us;
//预装载使能
TIM4->CR1 |=(0x1<<7);
//5.选择计数方式 递增计数
TIM4->CR1 &=~(0x1<<4);
//6.关闭更新中断
TIM4->DIER &=~(0x1<<0);
//7.进入NVIC设置
my_nvic_init(7-2,0,3,TIM4_IRQn);
//8.关闭计数器使能
TIM4->CR1 &=~(0x1<<0);
return FALSE;
}
inline void
vMBPortTimersEnable( )
{
/* Enable the timer with the timeout passed to xMBPortTimersInit( ) */
//打开更新中断
TIM4->DIER |=(0x1<<0);
TIM4->CNT=0;
//打开计数器使能
TIM4->CR1 |=(0x1<<0);
}
inline void
vMBPortTimersDisable( )
{
/* Disable any pending timers. */
//关闭更新中断
TIM4->DIER &=~(0x1<<0);
TIM4->CNT=0;
//关闭计数器使能
TIM4->CR1 &=~(0x1<<0);
}
/* Create an ISR which is called whenever the timer has expired. This function
* must then call pxMBPortCBTimerExpired( ) to notify the protocol stack that
* the timer has expired.
*/
void prvvTIMERExpiredISR( void )
{
( void )pxMBPortCBTimerExpired( );
}
void TIM4_IRQHandler(void)
{
if((TIM4->DIER&(0x1<<0))!=0)
{
//清中断
TIM4->SR &=~(1<<0);
prvvTIMERExpiredISR();
}
} |
-
|