OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2427|回复: 5

求大神帮忙解决单相电模块与stm32串口1的收发数据问题

[复制链接]

2

主题

13

帖子

0

精华

新手上路

积分
41
金钱
41
注册时间
2017-7-30
在线时间
17 小时
发表于 2017-8-14 09:01:52 | 显示全部楼层 |阅读模式
10金钱
最近在学stm32的串口通讯,刚好也接触到单相电模块,然后想单相电模块与32开发板进行数据转送,但总是不成功。该单相电模块的指令解析为:

unsigned int calccrc(unsigned char crcbuf,unsigned int crc)
{
unsigned char i;
unsigned char chk;
crc=crc ^ crcbuf;
for(i=0;i<8;i++)
{
chk=( unsigned char)(crc&1);
crc=crc>>1;
crc=crc&0x7fff;
if (chk==1)
crc=crc^0xa001;
crc=crc&0xffff;
}
return crc;
}
unsigned int chkcrc(unsigned char *buf,unsigned char len)
{
unsigned char hi,lo;
unsigned int i;
unsigned int crc;
crc=0xFFFF;
for(i=0;i<len;i++)
{
crc=calccrc(*buf,crc);
buf++;
}
hi=( unsigned char)(crc%256);
lo=( unsigned char)(crc/256);
crc=(((unsigned int)(hi))<<8)|lo;
return crc;
}
void read_data(void)
{
union crcdata
{
unsigned int word16;
unsigned char byte[2];
}crcnow;
if((Clock.Second%2)==1) //2 秒读一次
{
Tx_Buffer[0]=Read_ID; //抄读模块的 ID 号
Tx_Buffer[1]=0x03;
Tx_Buffer[2]=0x00;
Tx_Buffer[3]=0x48;
Tx_Buffer[4]=0x00;
Tx_Buffer[5]=0x06;
crcnow.word16=chkcrc(Tx_Buffer,6);
Tx_Buffer[6]=crcnow.byte[1]; //CRC 效验低字节在前
Tx_Buffer[7]=crcnow.byte[0];
Send_data(8); //发送 8 个数据,请根据单片机类型自己编程  (这里我们stm32开发板应该怎么配置呢?
}
}
void Analysis_data(void)
{
unsigned char i;
union crcdata
{
unsigned int word16;
unsigned char byte[2];
}crcnow;
if(Comm[1].Status==2) //接收完成           这里怎么理解?
{
if(RX_Buffer[0]==Read_ID) //确认 ID 正确
{
crcnow.word16=chkcrc(RX_Buffer,Comm[1].nRx-2); //Comm[1].nRx 是接收数据长度   这个数据长度又怎么理解,怎么配置好?
if((crcnow.byte[0]==RX_Buffer[Comm[1].nRx-1])&&(crcnow.byte[1]==RX_Buffer[Comm[1].nRx-2])) //CRC
效验
{
Voltage_data=(((unsigned int)(RX_Buffer[3]))<<8)|RX_Buffer[4]; //Voltage_data 为 unsigned int 型
Current_data=(((unsigned int)(RX_Buffer[5]))<<8)|RX_Buffer[6]; //Current_data 为 unsigned int 型
Power_data=(((unsigned int)(RX_Buffer[7]))<<8)|RX_Buffer[8]; //Power_data 为 unsigned int 型
Energy_data=(((unsigned long)(RX_Buffer[9]))<<24)|(((unsigned long)(RX_Buffer[10]))<<16)|(((unsigned
long)(RX_Buffer[11]))<<8)|RX_Buffer[12]; ////Energy_data 为 unsigned long 型
Pf_data=(((unsigned int)(RX_Buffer[13]))<<8)|RX_Buffer[14]; //Pf_data 为 unsigned int 型
}
}
Comm[1].Status=0; //切换回接收数据状态
}
}  


求大神们帮忙解惑,困惑很久了,想不通!!!


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

13

帖子

0

精华

新手上路

积分
41
金钱
41
注册时间
2017-7-30
在线时间
17 小时
 楼主| 发表于 2017-8-14 09:23:47 | 显示全部楼层
各路朋友,请帮忙顶一下啊!
回复

使用道具 举报

32

主题

286

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1364
金钱
1364
注册时间
2014-3-27
在线时间
358 小时
发表于 2017-8-14 09:52:36 | 显示全部楼层
1,串口配置可以找找手册对着来吧,没什么东西,你应该清楚的。就是串口初始化时,注意BAUD率,奇偶校验,数据长度,发使能。
请问 Send_data(xx)函数原型是什么,最好贴上来,Send_data(8)肯定是不对的。应该是发数组Tx_Buffer。你有开发手册吧,对照着来。没什么难度。
2,Comm[1].Status==2,就是结构体数组啊, COMM 数组中第2个结构体的 成员.Status 是否为2.  你对照着来。
3,Comm[1].nRx和 第2问相同。
回复

使用道具 举报

2

主题

13

帖子

0

精华

新手上路

积分
41
金钱
41
注册时间
2017-7-30
在线时间
17 小时
 楼主| 发表于 2017-8-14 10:17:42 | 显示全部楼层
wjfhsym 发表于 2017-8-14 09:52
1,串口配置可以找找手册对着来吧,没什么东西,你应该清楚的。就是串口初始化时,注意BAUD率,奇偶校验, ...

恩, 感觉我已经是对这手册看了,但还是检测不出数据,我的全文件是这样子的:

文件.rar

5.39 MB, 下载次数: 118

回复

使用道具 举报

32

主题

286

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1364
金钱
1364
注册时间
2014-3-27
在线时间
358 小时
发表于 2017-8-14 12:00:36 | 显示全部楼层
本帖最后由 wjfhsym 于 2017-8-14 14:32 编辑
路上的上年 发表于 2017-8-14 10:17
恩, 感觉我已经是对这手册看了,但还是检测不出数据,我的全文件是这样子的:

你需要理清楚整个流程。
你的单相模块数据  需要通过read_data(void)这个函数去读出来,首先你发送的8字节数据要成功给到单相模块。给你几个UART1发送函数。
void USART1_SendNByte(u8 *data, u16 num)//
{
        while(num--)
        {
                USART_SendData(USART1, *data++);
                while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
               
        }
}

void USART1_SendString(u8 *str)
{
        while(*str != '\0')
        {
                while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
                USART_SendData(USART1, *str);               
                str++;
        }
}




void UART1_SentData(uint8_t * Buf,uint16_t Length)
{
  uint16_t i;
  for(i=0;i<Length;i++)
  {
          USART_SendData(USART1, Buf);
          while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);                                 
  } while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);           




则        Send_data(8); 就可以做出相应更改。同时要在main 函数while(1)中 调用  read_data()函数, 发送给单相模块完成后。单相模块会通过串口发送相关电压电流参数到CPU.
此时你再用串口接收中断  ,接收相关数据 。 这个中断接收函数也就是 Analysis_data(void)函数, 不过  函数名字要修改,为void USART1_IRQHandler(void),内容放进去,并做相应修改。
void USART1_IRQHandler(void)
{
        
uint8_t i;

  if(USART_GetITStatus(USART1,USART_IT_RXNE))
  {

        //相关内容         
  }
  USART_ClearITPendingBit(USART1,USART_IT_RXNE);
}



串口1中断内会得到  单相模块的电压 电压  功率等数据(变量),你再在主函数中的LCD 显示内调用这些变量。



回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165462
金钱
165462
注册时间
2010-12-1
在线时间
2114 小时
发表于 2017-8-15 00:55:56 | 显示全部楼层
仿真找问题
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-4-20 17:48

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表