关于STM8L152的UASRT问题
我程序如下
void clock_init(void)
{
//Fmaster = 8.00M
//Fcpu = Fmaster
CLK_SWR = 0x04;
CLK_SWCR |= 0x02;
Delay(1000);
while((CLK_SWCR && 0x01 ) == 0) // Wait switch ready
{
_NOP();
}
CLK_CKDIVR = 0x00;
CLK_ECKR |=0X01; //使能外部时钟
Delay(1000);
while((CLK_ECKR && 0x02 ) == 0) // 使能 ready
{
_NOP();
}
CLK_CSSR |= 0x01;
CLK_PCKENR1 |=0X27;//开启时钟,stm8的外设时钟可控
CLK_PCKENR2 |=0X20;//开启时钟,stm8的外设时钟可控
SYSCFG_RMPCR1 = 0x20;
}
void uart0_init(void)
{
USART1_BRR2 = 0x00; //disable while setting baud rate
USART1_BRR1 = 0x00;
USART1_CR1 = 0x00;
USART1_CR3 = 0x00;
USART1_SR_TC = 0;
switch (data_value)
{
case 0:
USART1_CR1 |= 0x00; //异步 8位数据 1停止位 无校验
break;
case 2:
USART1_CR1 |= 0x06; //异步 8位数据 1停止位 奇校验
break;
case 1:
USART1_CR1 |= 0x04; //异步 8位数据 1停止位 偶校验
break;
default:
break;
}
//8000000/9600=0x0341
//8000000/4800 = 0x0682
switch (baud_value)
{
case 0:
USART1_BRR2 = 0x1A; //set baud rate as 1200
USART1_BRR1 = 0xA0;
break;
case 1:
USART1_BRR2 = 0x05; //set baud rate as 2400
USART1_BRR1 = 0xD0;
break;
case 2:
USART1_BRR2 = 0x02; //set baud rate as 4800
USART1_BRR1 = 0x68;
break;
case 3:
USART1_BRR2 = 0x01; //set baud rate as 9600
USART1_BRR1 = 0x34;
break;
default:
break;
}
USART1_CR2_RIEN=1;
USART1_CR2_REN=1;
USART1_CR2_TCIEN=0;
USART1_CR2_TIEN=0;
USART1_CR2_TEN=0;
RECE_485;
cnt_tras_num=0;
cnt_rece_num=0;
uar_rece_succeed=0;
uar_tras_succeed=0;
fg_now_receive=0;
checkoutError = 0;
}
#pragma vector=USART_R_RXNE_vector
__interrupt void uart0_rx_isr(void)
{
uchar temp;
if ((USART1_SR_FE==1)||(USART1_SR_PE==1))
{
checkoutError = 1;
}
temp = USART1_SR;
temp = USART1_DR;
uar_rece_buf[cnt_rece_num] = temp;
USART1_SR_RXNE=0;
checkoutError = 0;
if (uar_rece_buf[0] != addr_value)
{
cnt_rece_num = 0;
checkoutError = 1;
}
else if (cnt_rece_num<30)
{
cnt_rece_num++;
}
}
#pragma vector = USART_T_TC_vector
__interrupt void uart0_tx_isr(void)
{
if (sendPosi<cnt_tras_num)
{
++sendPosi;
USART1_DR = uar_tras_buf[sendPosi];
}
else
{
USART1_CR2_RIEN=1;
USART1_CR2_REN=1;
USART1_CR2_TCIEN=0;
USART1_CR2_TIEN=0;
USART1_CR2_TEN=0;
RECE_485;
cnt_tras_num=0;
cnt_rece_num=0;
uar_rece_succeed=0;
uar_tras_succeed=0;
fg_now_receive=0;
checkoutError = 0;
}
USART1_SR_TC = 0;
USART1_SR_TXE = 0;
}
void beginSend(void)
{
USART1_CR2_TCIEN=1;
USART1_CR2_TIEN=1;
USART1_CR2_TEN=1;
SEND_485;
sendPosi = 0;
USART1_DR = uar_tras_buf[sendPosi];
USART1_SR_TC = 0;
USART1_SR_TXE = 0;
}
void checkComm0Modbus(void)
{
uint crcData;
uint tempData;
if(cnt_rece_num>1)
switch(uar_rece_buf[1])
{
case 6://设置单个寄存器
if(cnt_rece_num >= 8)
{
USART1_CR2_RIEN=0;
USART1_CR2_REN=0;
if((uar_rece_buf[0]==addr_value) && (checkoutError==0))
{
crcData = crc16(uar_rece_buf,6);
if(crcData == uar_rece_buf[7]+(uar_rece_buf[6]<<8))
{//校验正确
if(uar_rece_buf[1] == 6)
{
readRegisters(); }
}
else
checkoutError=1;
cnt_rece_num = 0;
}
else if(uar_rece_buf[0]!=addr_value)
checkoutError=1;
cnt_rece_num = 0;
}
break;
default:
{ checkoutError=1;
cnt_rece_num = 0;
}break;
}
}
void readRegisters(void)
{
uint addr;
uint tempAddr;
uint crcData;
uint readCount;
uint byteCount;
uint i;
uint tempData = 0;
//起始地址
addr = (uar_rece_buf[2]<<8) + uar_rece_buf[3];
tempAddr = addr & 0xffff;
//寄存器数量
readCount = (uar_rece_buf[4]<<8) + uar_rece_buf[5]; //要读的个数
byteCount = readCount * 2;
for(i=0; i<byteCount; i+=2,tempAddr++)
{
tempData = getRegisterVal(tempAddr);
uar_tras_buf[i+3] = tempData >> 8;
uar_tras_buf[i+4] = tempData & 0xff;
}
uar_tras_buf[0] = addr_value;
uar_tras_buf[1] = 0x03;
uar_tras_buf[2] = byteCount;
byteCount += 3;
crcData = crc16(uar_tras_buf,byteCount);
uar_tras_buf[byteCount] = crcData >> 8;
byteCount++;
uar_tras_buf[byteCount] = crcData & 0xff;
cnt_tras_num = byteCount + 1;
beginSend();
}
我主程序里循环执行的是checkComm0Modbus();
现在的问题是发送回的数据一直不正确,并且检测了一下接收到的数据,只有第一次正常,第二次就不正常了,会一直停留在接收终端中,找不到原因,求帮助 |