打印
[STM32F1]

STM32例程+电力高压无线测温

[复制链接]
1872|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 山东电子小菜鸟 于 2017-9-25 14:36 编辑

       电力设备安全可靠性是超大规模输配电和电网安全保障的重要环节,尤其我国正处于经济快速增长时期,国家电网的电力供电负荷日益增加,在持续扩大供电同时给电网电器设备带来一系列的安全问题。为尽可能的避
免各类电力事故,电力设备安全运行实时监控的任务迫在眉睫,无线测温采用高电压等电位温度测量技术,实现
高压设备的温度在线监测,助力智能电网建设。
无线测温:发送部分与接收终端,
采用MCU型号:STM32F103C8
软件平台:MDK5.12
STM32F103C8官方地址:http://www.st.com/content/st_com ... x1/stm32f051c8.html
网络:

发送设备:

接收终端:


0TEM SEN PRO.zip (287.62 KB)
0TEM REC PRO.zip (3.33 MB)
沙发
山东电子小菜鸟|  楼主 | 2017-9-25 14:10 | 只看该作者
接收电路图:








使用特权

评论回复
板凳
山东电子小菜鸟|  楼主 | 2017-9-25 14:11 | 只看该作者
发送电路:




使用特权

评论回复
地板
山东电子小菜鸟|  楼主 | 2017-9-25 14:13 | 只看该作者
//在指定为是显示数字串
//(当数字为十六进制时,调用此函数,例如显示nrfID:0x01,0xE1,0xE2,0xE3;十进制类型的串调用dispen)
void disphex(uint8_t x, uint8_t y, const uint8_t *pData ,uint8_t num)
{
  uint8_t i;
  setxy( x, y ) ;
  for(i=0;i<num;i++)
  {
    LCD_Writedate(*(code+(*pData>>4)));
        LCD_Writedate(*(code+(*pData&0x0f)));
        pData++;
  }
}
//在指定位置输出字符串
void dispen( uint8_t x, uint8_t y, const uint8_t *pData ,uint8_t num)
{
  uint8_t i;
  setxy( x, y ) ;
  for(i=0;i<num;i++)
  {
    LCD_Writedate( *pData++ ) ;
  }            
}
//在指定位置输出汉字//汉字显示的时候是num*2,注意一下。
void dispch( uint8_t x, uint8_t y, const uint8_t *pData ,uint8_t num)
{
  uint8_t i;
  setxy( x, y ) ;
  for(i=0;i<(num*2);i++)
  {
    LCD_Writedate( *pData++ ) ;
  }            
}

//显示开机画面:
//
//                无线测温终端
//                                          
//                                        V1.0
void **(void)
{
        uint8_t *version="V1.0";

        LCD_Init();
        LCD_CLR();
        dispen(0,0,"ID:",3);
        disphex(2,0,&dizhi,1);
        dispch(1,1,"无线测温终端",6);//此处显示:无线测温终端V2.0
        dispen(6,3,version,4);  
        Delay_10us(300000); //delay 10ms
}

//显示节点温度画面:
//----------------------------
//0123456789012345
//1#  上        下          
//A:
//B:
//C:
//----------------------------
void NodeDisp(void)
{
        LCD_CLR();
//        dispen(0,0," #",2);
        dispch(3,0,"上    下",4);
        dispen(0,1,"A:",2);
        dispen(0,2,"B:",2);
        dispen(0,3,"C:",2);         
}

//显示参数设置画面:(以十六进制显示)
//临时只设置显示终端的设备dizhi,同时能显示显示flash中的nrf ID.
//----------------------------
//0123456789012345
//ID: FF          
//01E1E2E302E1E2E3
//03E1E2E304E1E2E3
//05E1E2E306E1E2E3
//----------------------------
void SetDisp(void)
{
       
        LCD_CLR();//初始化LCD
        dispen(0,0,"ID:",3);
        //disphex(0,3,unirfaddr.addr,8);//显示终端NRFID       
        disphex(2,0,&dizhi,1);
        disphex(4,0,&unirfaddr.addr[0],4);
        disphex(0,1,unirfaddr.addr,8);//unirfaddr.addr[] ,开机时从flash中读出并存到unirfaddr.addr[]所在的联合体中。
        disphex(0,2,unirfaddr.addr+8,8);
        disphex(0,3,unirfaddr.addr+16,8);       
}
//显示保存与取消的提示界面
//默认时保存字体颜色置反
//----------------------------
//0123456789012345          
//
//
//    是  否
//
//----------------------------
void SaveDisp(void)
{
        LCD_CLR();
        dispch(2, 2, "是  否", 3);
}

/*******************************************************
*函数名:TempDisp
*描述  :在屏幕上显示温度或电压值
*输入  :nod:节点,传递数据
                 n:节点下标,与LCD屏上的显示位置关联,n=0---5
                 status: 判断显示温度或电压的标志,SET显示温度,RESET显示电压
*输出  :在屏幕上显示出相关的数据
*调用  :外部调用
*******************************************************/
void TempDisp(StrNode nod, uint8_t n, FlagStatus status)
{   
          float tmp;//一般情况下nod参数传来的温度值0-1750        Float        -50~125℃
                uint16_t tmpbuf;
                uint8_t buf[10];
                int32_t len;

           if(SET==status) //温度
           {dispch(0,0,"温度",2);
                           tmpbuf=nod.temper<<8;
                        tmp=tmpbuf|(nod.temper>>8);//注意大小端,高低位对调
                        tmp=tmp*0.01-50.0;
                        len=sprintf(buf, "%3.2f", tmp);                        //返回值是字符串长度
      if(len>5)
        len=5;                               
           }
           else//电压
           {dispch(0,0,"电压",2);
                           tmpbuf=nod.voltage<<8;
                        tmp=tmpbuf|(nod.voltage>>8);//注意大小端,高低位对调
                        tmp=tmp*0.01;          
                        len=sprintf(buf, "%1.2f", tmp);       
//      len=len-1;                       
           }
          //在屏幕上合适的位置显示//n与之关联
          //----------------------------
                //0123456789012345
                //1#  上    下
                //A:
                //B:
                //C:
                //----------------------------
                switch(n)
                {
                        case 0:
                        case 1:
                        case 2:        dispen(2,n+1,buf,len);
                                        break;
                        case 3:
                        case 4:
                        case 5: dispen(5,n-2,buf,len);
                                        break;
                        default:break;
                }
          
}

使用特权

评论回复
5
山东电子小菜鸟|  楼主 | 2017-9-25 14:19 | 只看该作者
/*
* 函数名:NRF_Rx_Dat
* 描述  :用于从NRF的接收缓冲区中读出数据
* 输入  :rxBuf:用于接收该数据的数组,外部定义
* 输出  :接收结果,
* 调用  :外部调用
*/
u8 NRF_Rx_Dat(u8 *rxbuf, u8 *width)
{ u8 rxbuf1[1]={0xFF};
  u8 rxbuf2[1]={0xEE};
  u8 rxbuf3[1]={0xDD};
        u8 state;
        u8 state1;
        //u16 count = 999999;

        NRF_CE_HIGH();         //进入接收状态
        Delay_10us(10);
         /*等待接收中断*/
        //USART_OUT(USART1,"\r\n rx_state \r\n");
        while((NRF_Read_IRQ()!=0));        // && (count--)

        NRF_CE_LOW();           //进入待机状态
        Delay_10us(10);
        /*读取status寄存器的值  */
        state=SPI_NRF_ReadReg(STATUS);
        //USART_OUT(USART1,"\r\n rx_state:%d \r\n",state);

        /* 清除中断标志*/
        SPI_NRF_WriteReg(NRF_WRITE_REG+STATUS,state);

        state1=SPI_NRF_ReadReg(STATUS);
        //USART_OUT(USART1,"\r\n rx_state:%d \r\n",state1);

        /*判断是否接收到数据*/
        if(state&RX_DR)                                 //接收到数据
        {
          *width=SPI_NRF_WriteReg(R_RX_PL_WID,NOP);    //Read RX payload width for the top R_RX_PAYLOAD in the RX FIFO 获取RX payload的长度
      if(*width > 0x20)//判断是不是超出了最大长度,如果是,RX FIFO里的内容也是错误的。
      {
          SPI_NRF_WriteReg(FLUSH_RX,NOP);          //清除RX FIFO寄存器
                                        USART_OutData(USART1,rxbuf1,0x01);
                                        USART_OutData(USART1, rxbuf, *width);
          return ERROR;
      }
          SPI_NRF_ReadBuf(RD_RX_PLOAD,rxbuf,*width);//读取数据
          SPI_NRF_WriteReg(FLUSH_RX,NOP);          //清除RX FIFO寄存器
          return RX_DR;
        }
        else
                USART_OutData(USART1,rxbuf2,0x01);
                USART_OutData(USART1, rxbuf, *width);
                return ERROR;                    //没收到任何数据
}


使用特权

评论回复
6
山东电子小菜鸟|  楼主 | 2017-9-25 14:27 | 只看该作者
#pragma vector=TIMER0_A0_VECTOR
__interrupt void ta0_isr(void)//timer0  a0中断
{  
  TAR = 0;
  if(++time1.count == rxtime)//1s  rxtime为1
  {
    time1.count = 0;
    time1.timer[2]++;
    if(time1.timer[2] == adtime)//5s  adtime为125
    {
//     ADC10CTL0 = SREF_1 + ADC10SHT_1 + ADC10SR + REF2_5V + REFOUT  + ADC10IE;
      ADC10CTL0 |= REFON + ADC10ON;//在此配置ADC10参考电压使能。
      if(adflag == ON)//采集温度
      {// ADC10_SETTINGS1 ();
        adflag = OFF;
        channelflag = 0;//0为INCH_0,1为INCH_11
        ADC10CTL1 &= ~INCH_11;
        ADC10CTL1 |= INCH_0;//INCH_0+CONSEQ0;
        ADC10AE0 |= BIT0;//使AD0输入
//       delay_us(75000);
        ADC10CTL0 |= ENC + ADC10SC;//开始采样和转换过程
        //ADC10_ChannelSet(INCH_0);     
        //while(ADC10CTL1&BUSY);
//        delay_us(50);//此时间应该再单独测算一下,保证采集开始并转换完成其间轻易不被定时器中断。
      }
      else if(adflag == OFF)//采集电池电压
      {// ADC10_SETTINGS2 ();
        adflag = ON;
        channelflag = 1;//0为INCH_0,1为INCH_11
        ADC10AE0 = 0x0000;
        ADC10CTL1 |= INCH_11;
        ADC10CTL0 |= ENC + ADC10SC;
        //ADC10_ChannelSet(INCH_11);
        //while(ADC10CTL1&BUSY);
//        delay_us(90);
      }
      else ;
      
   /*   ADC10CTL0 &= ~ENC;
      ADC10CTL0 &= ~ADC10ON;
      ADC10CTL0 &= ~REFON;//关闭参考电压使能
      
      time1.timer[2] = 0;
      time1.timer[1]++;*/
    }
    if(time1.timer[1] == report1)//10s
    {
       time1.timer[0]++;
      if(time1.timer[0]==report2)
      {//填充发送数据:
      //txbuf[RFSIZE]={0xAA, 0x75, 0x00, 0x62, 0x00};        //发送缓冲
/*      txbuf[2]=0x0c;//不加报头的数据长度,数据长度定义见nRF无线协议格式文档
      txbuf[8]=temper>>8;
      txbuf[9]=temper;
      txbuf[10]=voltage>>8;
      txbuf[11]=voltage;
      
      NRF_TX_Mode();//在配置完发送模式寄存器后,进入休眠模式。
      NRF_Tx_Dat(txbuf, 14); //在发送数据时从休眠模式退出,进入发送模式。
      NRF_RX_Mode();//在配置完接收模式寄存器后,进入休眠模式。*/
      SendBuf();
      time1.timer[0] =0;   
      }
      time1.timer[1] = 0;
     }
/*   if(time1.timer[0] == 2)
    {
      time1.timer[0] = 0;//time1.timer[1] = time1.timer[2] = 0;
    }*/
  }
}

/*
*优化,减少CODE memory的使用,不使用函数调用的方法
void ADC10_ChannelSet(uint channel)
{
    switch(channel)
    {
        case INCH_0:
                channelflag = 0;
                ADC10CTL1 &= ~INCH_11;
                ADC10CTL1 |= INCH_0;
                ADC10AE0 |= BIT0;
                ADC10CTL0 |= ENC + ADC10SC;
                break;
        case INCH_11:
                channelflag = 1;
                ADC10AE0 = 0x0000;
                ADC10CTL1 |= INCH_11;
                ADC10CTL0 |= ENC + ADC10SC;
                break;
        default:
                break;               
      
    }
}
*/
short Temperature_Measure(short adcmem)
{
  //折半法查找,寻找adcmem在ADC10MEMTab表中的位置,当跟表中的值不相等时,找出其左右两个值的位置。
  short low = 0;
  short high = TabSize;
  short mid;
       
  if(adcmem < ADC10MEMTab[low] ||  adcmem > ADC10MEMTab[high])
      return 0x7fff;//采集出错时返回的0xffff;
       
  while(high >= low)
  {
      mid = (low + high) / 2;
      if(adcmem > ADC10MEMTab[mid])
          low = mid + 1;
      else
          high = mid - 1;
   }//low=high+1
  if(adcmem == ADC10MEMTab[low])
      return (low-20)*10;
  else
      return ( (adcmem - ADC10MEMTab[low-1])*10 / (ADC10MEMTab[low] - ADC10MEMTab[low-1]) + (low-21)*10 );
}

使用特权

评论回复
7
mmuuss586| | 2017-9-25 18:14 | 只看该作者

不错;

使用特权

评论回复
8
gujiamao12345| | 2017-9-25 18:39 | 只看该作者
版主们都好厉害!!!

使用特权

评论回复
9
队长shiwo| | 2017-9-25 18:43 | 只看该作者
说好的例程,版主们都是大神,都是比例程还牛X的项目,厉害厉害

使用特权

评论回复
10
yzqok| | 2017-9-26 10:04 | 只看该作者
顶一个

使用特权

评论回复
11
gqy001| | 2019-7-22 14:14 | 只看该作者
看看学习

使用特权

评论回复
12
shizaigaole| | 2019-7-22 14:43 | 只看该作者
除了接收端采用stm32显示一下数据,别的和stm32有半毛钱关系??

使用特权

评论回复
13
gqy001| | 2019-8-20 16:46 | 只看该作者
看看!!!!

使用特权

评论回复
14
1021256354| | 2019-8-22 14:33 | 只看该作者
2.4G能有多远?????部署有问题

使用特权

评论回复
15
leo2002z| | 2020-4-30 10:54 | 只看该作者
在实际环境中运行如何呢?STM32在这种高压电强电磁环境中运行如何呢?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:qq:641208111;技术交流群:377640799 大学电子竞赛预热赛开赛啦~千元大奖等你来拿火热进行中!!点击参加活动 欢迎加个人QQ:641208111一起交流合作

140

主题

3082

帖子

23

粉丝