前言

毕设用了IM1266模块联网传数据,但是苦于没有资料,做毕设的过程很煎熬的,参考了网上的类似的IM1281B的驱动,修修补补下终于算是做出来了,现在写下此博客,供以后的自己和开发者参考。

代码

初始化函数:

void usart3_init(u32 bound)
{  NVIC_InitTypeDef NVIC_InitStructure;GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;//开启时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);    //开启GPIOB时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE); //串口3时钟使能//复位串口3USART_DeInit(USART3);//GPIO设置GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PB10GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化PB10GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入GPIO_Init(GPIOB, &GPIO_InitStructure);  //初始化PB11//USART设置USART_InitStructure.USART_BaudRate = bound;//波特率一般设置为4800;USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式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(USART3, &USART_InitStructure); //初始化串口 3//设置NVIC中断优先级NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0 ;//抢占优先级0NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//子优先级0NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//IRQ通道使能NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器//清理缓存IM266_clearBuf();   //使能接收中断USART_ITConfig(USART3, USART_IT_RXNE|USART_IT_IDLE, ENABLE);//开启中断   USART_ITConfig(USART3, USART_IT_IDLE, ENABLE);//开启中断   USART_Cmd(USART3, ENAB

中断函数:

vu16  USART3_RX_STA=0;void USART3_IRQHandler(void)
{char Res; //一个一个字节接收数据if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)  {USART_ClearITPendingBit(USART3, USART_IT_RXNE);Res =USART_ReceiveData(USART3);             if(USART3_RX_STA<USART3_MAX_RECV_LEN)  //接收的字符串{Rx_Buffer_Pre[USART3_RX_STA]=Res;USART3_RX_STA++;         }}//空闲中断,在收完数据后自动发送  if(USART_GetITStatus(USART3, USART_IT_IDLE) != SET)  {receive_finished=1;USART_ClearITPendingBit(USART3, USART_IT_IDLE);} USART3->SR;USART3->DR;
//  DEBUG_LOG("接收到IM1266数据");
}

读写函数:

//3:(地址:01H 命令:03H 数据长度:20H)+32:(数据段4x8=32)+2(CRC校验)=37:实际长度
unsigned char   Tx_Buffer_Pre[8];
unsigned char   Rx_Buffer_Pre[37];
//存放默认单位的数据:0.1V 0.001A等
unsigned char   Read_ID=0x01;
unsigned long   Voltage_data;
unsigned long   Current_data;
unsigned long   Power_data;
unsigned long   Energy_data;
unsigned long   Pf_data;
unsigned long   CO2_data;
unsigned long   Temp_data;
unsigned long   HZ;
//存放常见单位的数据:1V 1A等
float Voltage_data_F;
float Current_data_F;
float Power_data_F;
float Energy_data_F;
float Pf_data_F;
float CO2_data_F;
float Temp_data_F;
float HZ_F;int  i=8;//此次发送数据的长度
int j=0;
int receive_finished;//完成标志位
int read_enable=0; //可读标志位
int reveive_numbe=37;//接收数据总长度
//自带
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;
}
//修改 只需更改Tx_Buffer_Pre即可实现其他指令
void read_data(void)
{union  crcdata{unsigned int word16; unsigned char  byte[2];}crcnow;if(read_enable==1)    // 到时间读数据{read_enable=0;Tx_Buffer_Pre[0]=Read_ID; //模块的 ID 号,默认 ID 为 0x01 Tx_Buffer_Pre[1]=0x03;Tx_Buffer_Pre[2]=0x00; Tx_Buffer_Pre[3]=0x48;Tx_Buffer_Pre[4]=0x00; Tx_Buffer_Pre[5]=0x08; crcnow.word16=chkcrc(Tx_Buffer_Pre,6);Tx_Buffer_Pre[6]=crcnow.byte[1];   //CRC 效验低字节在前Tx_Buffer_Pre[7]=crcnow.byte[0];}for(j=0;j<i;j++)                   //循环发送数据01 03 00 48 00 08 C4 1A{while(USART_GetFlagStatus(USART3,USART_FLAG_TC)==RESET); //串口三 循环发送,直到发送完毕   USART_SendData(USART3,Tx_Buffer_Pre[j]);}
//          DEBUG_LOG("发送IM1266读数据命令");
}
//修改
void Analysis_data(void){   union   crcdata{unsigned int word16;unsigned char   byte[2];}crcnow;if(receive_finished==1)   //接收完成{//          reveive_numbe=USART3_RX_STA;receive_finished=0; if((Rx_Buffer_Pre[0]==0x01)||(Rx_Buffer_Pre[0]==0x00))    //确认 ID 正确{printf("\r\n确认 ID 正确\r\n");//串口一来打印接受电压值crcnow.word16=chkcrc(Rx_Buffer_Pre,reveive_numbe-2);  if((crcnow.byte[0]==Rx_Buffer_Pre[reveive_numbe-1])&&(crcnow.byte[1]==Rx_Buffer_Pre[reveive_numbe-2]))//确认 CRC 校验正确{//                  printf("\r\n%d\r\n", USART3_RX_STA);DEBUG_LOG("==================================================================================");Voltage_data=(((unsigned long)(Rx_Buffer_Pre[3]))<<24)|(((unsigned long)(Rx_Buffer_Pre[4]))<<16)|(((unsigned long)(Rx_Buffer_Pre[5]))<<8)|Rx_Buffer_Pre[6];Voltage_data_F=(float)(Voltage_data*0.0001);printf("电压:%.4lf V\r\n",Voltage_data_F);//串口一来打印电压Current_data=(((unsigned long)(Rx_Buffer_Pre[7]))<<24)|(((unsigned long)(Rx_Buffer_Pre[8]))<<16)|(((unsigned  long)(Rx_Buffer_Pre[9]))<<8)|Rx_Buffer_Pre[10];Current_data_F=(float)(Current_data*0.0001);printf("电流:%.4lf A\r\n",Current_data_F);//串口一来打印电流Power_data=  (((unsigned long)(Rx_Buffer_Pre[11]))<<24)|(((unsigned long)(Rx_Buffer_Pre[12]))<<16)|(((unsigned   long)(Rx_Buffer_Pre[13]))<<8)|Rx_Buffer_Pre[14];Power_data_F=(float)(Power_data*0.0001);printf("功率:%.4lf W\r\n",Power_data_F);//串口一来打印功率Energy_data=(((unsigned   long)(Rx_Buffer_Pre[15]))<<24)|(((unsigned long)(Rx_Buffer_Pre[16]))<<16)|(((unsigned   long)(Rx_Buffer_Pre[17]))<<8)|Rx_Buffer_Pre[18];Energy_data_F=(float)(Energy_data*0.0001);printf("电能:%.4lf KWh\r\n",Energy_data_F);//串口一来打印电能Pf_data=     (((unsigned long)(Rx_Buffer_Pre[19]))<<24)|(((unsigned long)(Rx_Buffer_Pre[20]))<<16)|(((unsigned   long)(Rx_Buffer_Pre[21]))<<8)|Rx_Buffer_Pre[22];Pf_data_F=(float)(Pf_data*0.001);printf("功率因数:%.3lf \r\n",Pf_data_F); //串口一来打印接受功率因数CO2_data=     (((unsigned long)(Rx_Buffer_Pre[23]))<<24)|(((unsigned long)(Rx_Buffer_Pre[24]))<<16)|(((unsigned   long)(Rx_Buffer_Pre[25]))<<8)|Rx_Buffer_Pre[26];CO2_data_F=(float)(CO2_data*0.0001);printf("二氧化碳:%.4lf Kg\r\n",CO2_data_F);//串口一来打印接受二氧化碳Temp_data=   (((unsigned long)(Rx_Buffer_Pre[27]))<<24)|(((unsigned long)(Rx_Buffer_Pre[28]))<<16)|(((unsigned   long)(Rx_Buffer_Pre[29]))<<8)|Rx_Buffer_Pre[30];Temp_data_F=(float)(Temp_data*0.01);printf("温度:%.2lf °C\r\n",Temp_data_F);//串口一来打印接受二氧化碳HZ=                   (((unsigned long)(Rx_Buffer_Pre[31]))<<24)|(((unsigned long)(Rx_Buffer_Pre[32]))<<16)|(((unsigned   long)(Rx_Buffer_Pre[33]))<<8)|Rx_Buffer_Pre[34];HZ_F=(float)(HZ*0.01);printf("赫兹:%.2lf HZ\r\n",HZ_F);//串口一来打印接受单相交流电的赫兹DEBUG_LOG("==================================================================================");USART3_RX_STA=0;}else printf("// CRC 校验错误\r\n");}}else printf("\r\nreceive_finished标志位为0\r\n");}void IM266_clearBuf(void)  //清空USART3_RX_BUF内存 {int i;for(i=0;i<37;i++)Rx_Buffer_Pre[i]=0;}

主函数

 int main(void){ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);usart3_init(4800); //IM1266通讯串口DEBUG_LOG("UART3初始化          [OK]");while(1){read_enable=1;        //读数据使能read_data();         //读IM1266数据-中断接收数据-使能完成标志位delay_ms(2000);       //等待中断传输if(receive_finished){Analysis_data();receive_finished=0;}}
}

上图

用PC的效果:

串口调试的效果:

小程序演示的效果:

数据能正常能读取

感谢 良心不痛吗 关于IM1281B的代码,给了很大启发

IM1266在STM32F103C8T6下使用心得相关推荐

  1. 【嵌入式系统开发15】STM32F103C8T6下通过定时器Timer方式实现时间的精准控制,实现串口通信并让LED等周期性地闪烁

    本文目的是主要介绍通过STM32F103C8T6采用定时器Timer方式实现时间的精准控制,相当于给CPU上了一个闹钟,CPU平时处理其它任务,当定时时间到了以后,处理定时相关的任务.请设置一个5秒的 ...

  2. 夫妻双双中标2018年NSFC青基,顺便说下之前心得

    上次在小木虫发贴还是申请公派出国的时候,那时候也是跟一群虫子焦急的等待各位系统漏洞,玩的心惊胆战,最后顺利出国.所以这次基金申请也参与了各种玩法,将信将疑.那我就先将玩法和我们情况写在前面,给焦虑的虫 ...

  3. 世界崩塌前要写下游戏心得(持续更新)

    前言 有一部纪录片中问道,你为什么看电影?有人回答"想要体验不同的人生","可以看到丰富的故事,增加人生阅历","因为电影特效好看,很刺激" ...

  4. shell下 使用心得

    打印时间的命令 date +'%F %k:%M:%d' crontab启动计划任务,注意两件事情: 1)crontab里启动的脚本,如果需要读取文件,需要使用绝对路径,或者在脚本里cd到目录所在的绝对 ...

  5. thinkphp框架使用心得

    接触的第一个PHP框架就是TP,在使用的了一段时间后就放弃了,说实话TP的弊端挺多,之后又接触laravel框架,慢慢的就爱上laravel这个框架了.这段时间由于公司的原因,又不得不使用thinkp ...

  6. 使用android studio查看内存,Android Studio Profiler使用心得 检测内存泄露问题

    最近在分析app的内存泄露问题研究了下as的profiler功能  这里记录下个人心得 下面是个人心得 1.首先得出结论profiler不详细提供分析c或c++库进行的内存占用 其中包括android ...

  7. 计算机知识培训感言,计算机培训的心得体会

    心得体会是我们每一个人在生活或者学习中所产生的所思所想所感,写下这些心得体会可以帮助我们更好的认识事物.下面是由出国留学网小编为大家整理的"计算机培训心得体会",仅供参考,欢迎大家 ...

  8. 做互联网产品运营的一点心得

    一个网站运营团队大致粗略地可分成三个部门:产品部.设计部和技术部,产品部为核心,设计部和技术部为支撑,如果网站产品较多比如有资讯内容.论坛.博客.SNS等,那产品部会配备好几个人,每人负责一个产品.在 ...

  9. 【考研经验】2019双非应届生清华大学计算机专业课和复试心得

    转载于 王道论坛 原作者 lx444 双非328应届生上岸,专业课98.数学108.英语64.政治58 由于基础课比较水,就不误导大家了,说下专业课心得吧. 912肯定是按照清华上课的内容来,学堂在线 ...

最新文章

  1. 低层级GPU虚拟内存管理引论
  2. 计失败的一次js优化
  3. 200825C文件 复习
  4. python循环一百次_python循环
  5. django之关系及查询,数据类型,约束,分页
  6. Kali Linux破解WiFi教程
  7. Windows批处理文件(.bat文件和.cmd文件)介绍以及简单使用
  8. android studio + ndk + cmake + jna +sqlite c层报错SQLITE_CANTOPEN(14),SQLITE_MISUSE(21)问题
  9. cad菜单栏快捷键_干货|如何快速将图片转换成CAD文件格式
  10. 【转载】游戏场景设计、构图的一些基本思考
  11. abaqus的python安装文件在哪_拓展abaqus python 模块
  12. 网易云邮箱发送邮件失败
  13. 将ipad作为Windows10系统的的扩展显示屏
  14. android虚拟机接收真实短信,向Android模拟器打电话发短信的简单方法
  15. 网站SEO的技巧都有哪些?快速增加权重靠谱吗?
  16. Android开发:使用EasyPay打造全能移动支付框架
  17. 客运售票员_汽车站售票员工作心得体会
  18. VScode跑街商场网页排版
  19. Android逆向工程(一)-Apktool使用
  20. linux分区500g分区方案,linux 硬盘分区 分区方案!!!

热门文章

  1. nginx的高级配置(4)——防盗链
  2. java游戏界面制作_软件设计之基于Java的连连看小游戏(二)——游戏基础界面的制作及事件的添加...
  3. C#数据库编程入门:病人管理系统
  4. 沪江CCtalk杨继珩:做有温度的技术,赋予未来教育更多可能!
  5. python进行数据分析------相关分析
  6. JD带你一文搞定HTML!(有图有代码)
  7. 再推荐Geogebra 5.0.xx一下
  8. C# Winform中集成Kodak实现调用扫描仪的功能
  9. (专升本)计算机协议名称
  10. 【算法专题】环状图(置换群)