找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4701|回复: 5
收起左侧

基于STM32F103RC的MLX90614源代码

  [复制链接]
ID:668705 发表于 2019-12-20 19:57 | 显示全部楼层 |阅读模式
实测可用

单片机源程序如下:
  1. #include "led.h"
  2. #include "delay.h"
  3. #include "key.h"
  4. #include "sys.h"
  5. #include "stdint.h"
  6. #include "usart.h"
  7. #include "mlx90614.h"
  8. #include "GUI.h"
  9. #include "Lcd_Driver.h"
  10. #include "TFT_demo.h"


  11. //STM32F103核心板例程
  12. //库函数版本例程
  13.          
  14. int main(void)
  15. {         
  16.          
  17.         u8 lcd_id[12];                        //存放LCD ID字符串
  18.         delay_init();                     //延时函数初始化         
  19.         NVIC_Configuration();          //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
  20.         uart_init(9600);                 //串口初始化为9600
  21.          LED_Init();                             //LED端口初始化
  22.          BEEP_Init();
  23.         Lcd_Init();         //1.44寸液晶屏--初始化配置
  24.         Lcd_Clear(GRAY0);//清屏
  25.         Gui_DrawFont_GBK16(0,16,RED,GRAY0," STM32 TFT 1.44 ");
  26.   Gui_DrawFont_GBK16(0,48,BLUE,GRAY0,"  嵌入式开发网   ");         
  27.         Gui_DrawFont_GBK16(0,64,BLUE,GRAY0,"mcudevcom ");
  28.          SMBus_Init();
  29.          float temp;
  30.          Lcd_Clear(GRAY0);//清屏
  31.         int a;
  32.          
  33.   while(1)
  34.         {                 
  35.                 temp = SMBus_ReadTemp();
  36.                 printf("温度 = %5.2f℃\r\n",temp);
  37.                 sprintf((char*)lcd_id,"%5.2f",temp);
  38.                 Gui_DrawFont_GBK16(0,10,BLUE,GRAY0,"Temperature:");
  39.                 DisplayButtonUp(30,28,85,52); //x1,y1,x2,y2
  40.                 Gui_DrawFont_GBK16(40,32,RED,GRAY0,lcd_id);//体温显示到TFT
  41.                 delay_ms(1000);        
  42.                 a=(int)temp;
  43.                 if(a<=30|a>=42)//启动蜂鸣器报警
  44.                 {
  45.                 GPIO_SetBits(GPIOC,GPIO_Pin_14);
  46.                
  47.                 }
  48.                 else        GPIO_ResetBits(GPIOC,GPIO_Pin_14);        
  49.                
  50.                 delay_ms(1000);        
  51.         }
  52. }
复制代码
  1. #include "mlx90614.h"
  2. #define ACK         0
  3. #define        NACK 1
  4. #define SA                                0x00 //从机地址,单个MLX90614时地址为0x00,多个时地址默认为0x5a
  5. #define RAM_ACCESS                0x00 //RAM access command
  6. #define EEPROM_ACCESS        0x20 //EEPROM access command
  7. #define RAM_TOBJ1                0x07 //To1 address in the eeprom

  8. #define SMBUS_PORT            GPIOB
  9. #define SMBUS_SCK                GPIO_Pin_6
  10. #define SMBUS_SDA                GPIO_Pin_7

  11. #define RCC_APB2Periph_SMBUS_PORT                RCC_APB2Periph_GPIOB

  12. #define SMBUS_SCK_H()            SMBUS_PORT->BSRR = SMBUS_SCK
  13. #define SMBUS_SCK_L()            SMBUS_PORT->BRR = SMBUS_SCK
  14. #define SMBUS_SDA_H()            SMBUS_PORT->BSRR = SMBUS_SDA
  15. #define SMBUS_SDA_L()            SMBUS_PORT->BRR = SMBUS_SDA

  16. #define SMBUS_SDA_PIN()            SMBUS_PORT->IDR & SMBUS_SDA //读取引脚电平


  17. /*******************************************************************************
  18. * 函数名: SMBus_StartBit
  19. * 功能  : 产生起始位
  20. * Input          : None
  21. * Output         : None
  22. * Return         : None
  23. *******************************************************************************/
  24. void SMBus_StartBit(void)
  25. {
  26.     SMBUS_SDA_H();                // Set SDA line
  27.     SMBus_Delay(5);            // Wait a few microseconds
  28.     SMBUS_SCK_H();                // Set SCL line
  29.     SMBus_Delay(5);            // Generate bus free time between Stop
  30.     SMBUS_SDA_L();                // Clear SDA line
  31.     SMBus_Delay(5);            // Hold time after (Repeated) Start
  32.     // Condition. After this period, the first clock is generated.
  33.     //(Thd:sta=4.0us min)
  34.     SMBUS_SCK_L();            // Clear SCL line
  35.     SMBus_Delay(5);            // Wait a few microseconds
  36. }

  37. /*******************************************************************************
  38. * 函数名: SMBus_StopBit
  39. * 功能: Generate STOP condition on SMBus
  40. * Input          : None
  41. * Output         : None
  42. * Return         : None
  43. *******************************************************************************/
  44. void SMBus_StopBit(void)
  45. {
  46.     SMBUS_SCK_L();                // Clear SCL line
  47.     SMBus_Delay(5);            // Wait a few microseconds
  48.     SMBUS_SDA_L();                // Clear SDA line
  49.     SMBus_Delay(5);            // Wait a few microseconds
  50.     SMBUS_SCK_H();                // Set SCL line
  51.     SMBus_Delay(5);            // Stop condition setup time(Tsu:sto=4.0us min)
  52.     SMBUS_SDA_H();                // Set SDA line
  53. }

  54. /*******************************************************************************
  55. * 函数名: SMBus_SendByte
  56. * 功能: Send a byte on SMBus
  57. * Input          : Tx_buffer
  58. * Output         : None
  59. * Return         : None
  60. *******************************************************************************/
  61. u8 SMBus_SendByte(u8 Tx_buffer)
  62. {
  63.     u8        Bit_counter;
  64.     u8        Ack_bit;
  65.     u8        bit_out;

  66.     for(Bit_counter=8; Bit_counter; Bit_counter--)
  67.     {
  68.         if (Tx_buffer&0x80)
  69.         {
  70.             bit_out=1;   // If the current bit of Tx_buffer is 1 set bit_out
  71.         }
  72.         else
  73.         {
  74.             bit_out=0;  // else clear bit_out
  75.         }
  76.         SMBus_SendBit(bit_out);                // Send the current bit on SDA
  77.         Tx_buffer<<=1;                                // Get next bit for checking
  78.     }

  79.     Ack_bit=SMBus_ReceiveBit();                // Get acknowledgment bit
  80.     return        Ack_bit;
  81. }

  82. /*******************************************************************************
  83. * 函数名: SMBus_SendBit
  84. * 功能: Send a bit on SMBus 82.5kHz
  85. * Input          : bit_out
  86. * Output         : None
  87. * Return         : None
  88. *******************************************************************************/
  89. void SMBus_SendBit(u8 bit_out)
  90. {
  91.     if(bit_out==0)
  92.     {
  93.         SMBUS_SDA_L();
  94.     }
  95.     else
  96.     {
  97.         SMBUS_SDA_H();
  98.     }
  99.     SMBus_Delay(2);                                        // Tsu:dat = 250ns minimum
  100.     SMBUS_SCK_H();                                        // Set SCL line
  101.     SMBus_Delay(6);                                        // High Level of Clock Pulse
  102.     SMBUS_SCK_L();                                        // Clear SCL line
  103.     SMBus_Delay(3);                                        // Low Level of Clock Pulse
  104. //        SMBUS_SDA_H();                                    // Master release SDA line ,
  105.     return;
  106. }

  107. /*******************************************************************************
  108. * Function Name  : SMBus_ReceiveBit
  109. * Description    : Receive a bit on SMBus
  110. * Input          : None
  111. * Output         : None
  112. * Return         : Ack_bit
  113. *******************************************************************************/
  114. u8 SMBus_ReceiveBit(void)
  115. {
  116.     u8 Ack_bit;

  117.     SMBUS_SDA_H();          //引脚靠外部电阻上拉,当作输入
  118.         SMBus_Delay(2);                        // High Level of Clock Pulse
  119.     SMBUS_SCK_H();                        // Set SCL line
  120.     SMBus_Delay(5);                        // High Level of Clock Pulse
  121.     if (SMBUS_SDA_PIN())
  122.     {
  123.         Ack_bit=1;
  124.     }
  125.     else
  126.     {
  127.         Ack_bit=0;
  128.     }
  129.     SMBUS_SCK_L();                        // Clear SCL line
  130.     SMBus_Delay(3);                        // Low Level of Clock Pulse

  131.     return        Ack_bit;
  132. }

  133. /*******************************************************************************
  134. * 函数名: SMBus_ReceiveByte
  135. * 功能: Receive a byte on SMBus
  136. * Input          : ack_nack
  137. * Output         : None
  138. * Return         : RX_buffer
  139. *******************************************************************************/
  140. u8 SMBus_ReceiveByte(u8 ack_nack)
  141. {
  142.     u8         RX_buffer;
  143.     u8        Bit_Counter;

  144.     for(Bit_Counter=8; Bit_Counter; Bit_Counter--)
  145.     {
  146.         if(SMBus_ReceiveBit())                        // Get a bit from the SDA line
  147.         {
  148.             RX_buffer <<= 1;                        // If the bit is HIGH save 1  in RX_buffer
  149.             RX_buffer |=0x01;
  150.         }
  151.         else
  152.         {
  153.             RX_buffer <<= 1;                        // If the bit is LOW save 0 in RX_buffer
  154.             RX_buffer &=0xfe;
  155.         }
  156.     }
  157.     SMBus_SendBit(ack_nack);                        // Sends acknowledgment bit
  158.     return RX_buffer;
  159. }

  160. /*******************************************************************************
  161. * 函数名: SMBus_Delay
  162. * 功能: 延时  一次循环约1us
  163. * Input          : time
  164. * Output         : None
  165. * Return         : None
  166. *******************************************************************************/
  167. void SMBus_Delay(u16 time)
  168. {
  169.     u16 i, j;
  170.     for (i=0; i<4; i++)
  171.     {
  172.         for (j=0; j<time; j++);
  173.     }
  174. }

  175. /*******************************************************************************
  176. * 函数名: SMBus_Init
  177. * 功能: SMBus初始化
  178. * Input          : None
  179. * Output         : None
  180. * Return         : None
  181. *******************************************************************************/
  182. void SMBus_Init()
  183. {
  184.     GPIO_InitTypeDef    GPIO_InitStructure;

  185.         /* Enable SMBUS_PORT clocks */
  186.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_SMBUS_PORT, ENABLE);

  187.     /*配置SMBUS_SCK、SMBUS_SDA为集电极开漏输出*/
  188.     GPIO_InitStructure.GPIO_Pin = SMBUS_SCK | SMBUS_SDA;
  189.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
  190.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  191.     GPIO_Init(SMBUS_PORT, &GPIO_InitStructure);

  192.     SMBUS_SCK_H();
  193.     SMBUS_SDA_H();
  194. }

  195. /*******************************************************************************
  196. * 函数名: SMBus_ReadMemory
  197. * 功能: READ DATA FROM RAM/EEPROM
  198. * Input          : slaveAddress, command
  199. * Return         : Data
  200. *******************************************************************************/
  201. u16 SMBus_ReadMemory(u8 slaveAddress, u8 command)
  202. {
  203.     u16 data;                        // Data storage (DataH:DataL)
  204.     u8 Pec;                                // PEC byte storage
  205.     u8 DataL=0;                        // Low data byte storage
  206.     u8 DataH=0;                        // High data byte storage
  207.     u8 arr[6];                        // Buffer for the sent bytes
  208.     u8 PecReg;                        // Calculated PEC byte storage
  209.     u8 ErrorCounter;        // Defines the number of the attempts for communication with MLX90614

  210.     ErrorCounter=0x00;                                // Initialising of ErrorCounter
  211.         slaveAddress <<= 1;        //2-7位表示从机地址
  212.         
  213.     do
  214.     {
  215. repeat:
  216.         SMBus_StopBit();                            //If slave send NACK stop comunication
  217.         --ErrorCounter;                                    //Pre-decrement ErrorCounter
  218.         if(!ErrorCounter)                             //ErrorCounter=0?
  219.         {
  220.             break;                                            //Yes,go out from do-while{}
  221.         }

  222.         SMBus_StartBit();                                //Start condition
  223.         if(SMBus_SendByte(slaveAddress))//Send SlaveAddress 最低位Wr=0表示接下来写命令
  224.         {
  225.             goto        repeat;                            //Repeat comunication again
  226.         }
  227.         if(SMBus_SendByte(command))            //Send command
  228.         {
  229.             goto        repeat;                            //Repeat comunication again
  230.         }

  231.         SMBus_StartBit();                                        //Repeated Start condition
  232.         if(SMBus_SendByte(slaveAddress+1))        //Send SlaveAddress 最低位Rd=1表示接下来读数据
  233.         {
  234.             goto        repeat;                     //Repeat comunication again
  235.         }

  236.         DataL = SMBus_ReceiveByte(ACK);        //Read low data,master must send ACK
  237.         DataH = SMBus_ReceiveByte(ACK); //Read high data,master must send ACK
  238.         Pec = SMBus_ReceiveByte(NACK);        //Read PEC byte, master must send NACK
  239.         SMBus_StopBit();                                //Stop condition

  240.         arr[5] = slaveAddress;                //
  241.         arr[4] = command;                        //
  242.         arr[3] = slaveAddress+1;        //Load array arr
  243.         arr[2] = DataL;                                //
  244.         arr[1] = DataH;                                //
  245.         arr[0] = 0;                                        //
  246.         PecReg=PEC_Calculation(arr);//Calculate CRC
  247.     }
  248.     while(PecReg != Pec);                //If received and calculated CRC are equal go out from do-while{}

  249.         data = (DataH<<8) | DataL;        //data=DataH:DataL
  250.     return data;
  251. }

  252. /*******************************************************************************
  253. * 函数名: PEC_calculation
  254. * 功能 : 数据校验
  255. * Input          : pec[]
  256. * Output         : None
  257. * Return         : pec[0]-this byte contains calculated crc value
  258. *******************************************************************************/
  259. u8 PEC_Calculation(u8 pec[])
  260. {
  261.     u8         crc[6];
  262.     u8        BitPosition=47;
  263.     u8        shift;
  264.     u8        i;
  265.     u8        j;
  266.     u8        temp;

  267.     do
  268.     {
  269.         /*Load pattern value 0x000000000107*/
  270.         crc[5]=0;
  271.         crc[4]=0;
  272.         crc[3]=0;
  273.         crc[2]=0;
  274.         crc[1]=0x01;
  275.         crc[0]=0x07;

  276.         /*Set maximum bit position at 47 ( six bytes byte5...byte0,MSbit=47)*/
  277.         BitPosition=47;

  278.         /*Set shift position at 0*/
  279.         shift=0;

  280.         /*Find first "1" in the transmited message beginning from the MSByte byte5*/
  281.         i=5;
  282.         j=0;
  283.         while((pec[i]&(0x80>>j))==0 && i>0)
  284.         {
  285.             BitPosition--;
  286.             if(j<7)
  287.             {
  288.                 j++;
  289.             }
  290.             else
  291.             {
  292.                 j=0x00;
  293.                 i--;
  294.             }
  295.         }/*End of while */

  296.         /*Get shift value for pattern value*/
  297.         shift=BitPosition-8;

  298.         /*Shift pattern value */
  299.         while(shift)
  300.         {
  301.             for(i=5; i<0xFF; i--)
  302.             {
  303.                 if((crc[i-1]&0x80) && (i>0))
  304.                 {
  305.                     temp=1;
  306.                 }
  307.                 else
  308.                 {
  309.                     temp=0;
  310.                 }
  311.                 crc[i]<<=1;
  312.                 crc[i]+=temp;
  313.             }/*End of for*/
  314.             shift--;
  315.         }/*End of while*/

  316.         /*Exclusive OR between pec and crc*/
  317.         for(i=0; i<=5; i++)
  318.         {
  319.             pec[i] ^=crc[i];
  320.         }/*End of for*/
  321.     }
  322.     while(BitPosition>8); /*End of do-while*/

  323.     return pec[0];
  324. }

  325. /*******************************************************************************
  326. * 函数名: SMBus_ReadTemp
  327. * 功能: 计算并返回温度值
  328. * Return         : SMBus_ReadMemory(0x00, 0x07)*0.02-273.15
  329. *******************************************************************************/
  330. float SMBus_ReadTemp(void)
  331. {   
  332.         return SMBus_ReadMemory(SA, RAM_ACCESS|RAM_TOBJ1)*0.02-273.15;
  333. }

  334. /*********************************END OF FILE*********************************/
复制代码


所有资料51hei提供下载:
MLX90614.7z (258.93 KB, 下载次数: 242)
回复

使用道具 举报

ID:282845 发表于 2020-2-29 11:37 | 显示全部楼层
谢谢分享!!!
回复

使用道具 举报

ID:715946 发表于 2020-4-30 15:54 | 显示全部楼层
这个不外接电阻可以吗
回复

使用道具 举报

ID:715946 发表于 2020-4-30 15:55 | 显示全部楼层
#define SMBUS_SCK_H()            SMBUS_PORT->BSRR = SMBUS_SCK这个是怎么实现的
回复

使用道具 举报

ID:384489 发表于 2020-6-28 14:42 | 显示全部楼层
感谢分享,今天恰好在调试MLX90614。
回复

使用道具 举报

ID:1009310 发表于 2022-3-9 19:58 | 显示全部楼层
你好 为什么我的测出来一直是绝对零度呢
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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