打印
[RISC-V MCU 应用开发]

【RISC-V MCU CH32V103测评】-温度上传至Onenet-shihengrui⑥

[复制链接]
537|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 nvjwiciw659 于 2020-12-7 09:26 编辑

最近出差,回到郑州发现暖气已经通了,有暖气的感觉真好.同时因为出差耽误了测评,现在我把之前搞得几个外设综合一下,做一个小DEMO,监测一下家里的温度.  

所用外设

* 1.GPIO 一直闪烁,表示运行状态
* 2.USART 串口,与8266通信必备
* 3.SPI 读写外部FLASH(记录上电次数,很无聊的一个功能)
* 4.TIM 定时器,用于计时
* 5.ADC 用于读取内部温度  


外观  



简单用杜邦线连了连,也没什么外观可言

GPIO  

这里只做了简单的点灯,通过计时器,1S中闪烁一次

USART&连接Onenet

上篇我写好了串口收发驱动,这次直接用就行,我们添加一些驱动,用的是最简单的HTTP协议,直接按文档POST即可,代码如下

#include "ESP.h"
    #include "tim.h"
    #include "usart.h"
    #include "debug.h"
   
    #include <stdio.h>
    #include <string.h>
   
    #define DEVID   "********"
   
    #define APIKEY  "********"
   
    extern float tem;
   
    char *const esp_inti_cmd[][2] = {
    "AT\r\n", "OK",
    "ATE0\r\n", "OK",
    "AT+CWMODE=3\r\n", "OK",
    "AT+CWJAP=\"********\",\"3673671040\"\r\n", "GOT IP",
    "AT+CIFSR\r\n", "OK",
    "AT+CIPSTART=\"TCP\",\"183.230.40.33\",80\r\n", "CONNECT",
    //"AT+CIPSEND=4\r\n", "OK",
    //"test", "SEND OK",
    0, 0};
   
    /*
    串口发送函数
    *str为指令
    len为指令长度
    */
    void ESP_SendString(unsigned char *str, unsigned short len)
    {
        uint8_t i;
        for(i=0;i<len;i++)
        {
            USARTx_SendByte(USART3, *(str+i));
        }
    }
   
    /*
    AT指令发送函数
    *cmd为AT指令
    *res为需匹配的数据
    timeOut未等待时间
    匹配成功返回 0
    匹配失败返回 1
    */
    _Bool ESP8266_SendCmd(char *cmd, char *res,uint16_t timeOut)
    {
        ESP_SendString((unsigned char *)cmd, strlen((const char *)cmd));//发送AT指令
   
        while(timeOut--)//等待
        {
            if(!uart2_rx.flag)                            //如果收到数据
            {
                if(strstr((const char *)uart2_rx.rx_buff, res) != NULL)       //如果匹配到数据
                {
                    CLEAR_UART2();                                   //清空缓存
                    return 0;
                }
            }
            Delay_Ms(1);
        }
        return 1;
    }
   
    /*
    服务器下发解析函数
    返回值为结构体
   
    ipd_rx.len
    非下发数据返回:0
    解析失败返回:-1
    正确解析返回:数据长度
    */
    IPD_RX ESP8266_GetIPD(void)
    {
        IPD_RX ipd_rx;
        uint8_t i;
        char *ptrIPD = NULL;
        ipd_rx.len = 0;
        ptrIPD = strstr((char *)uart2_rx.rx_buff, "IPD,");                //搜索“IPD”头
        if(ptrIPD == NULL)//没找到直接退出
        {
            ipd_rx.len = 0;
            return ipd_rx;
        }
        else
        {
            ptrIPD = strchr(ptrIPD, ',');                           //找到','
            ptrIPD++;
            for(i=0;i<10;i++)//获取数据长度
            {
                if((ptrIPD[i]>='0')&&(ptrIPD[i]<='9'))
                {
                    ipd_rx.len = ipd_rx.len*10+(ptrIPD[i]-'0');
                }
                else    break;
            }
            ptrIPD = strchr(ptrIPD, ':');                           //找到':'
            if(ptrIPD != NULL)
            {
                ptrIPD++;
                ipd_rx.IPD_buff = (uint8_t *)(ptrIPD);
                return ipd_rx;
            }
            else
            {
                ipd_rx.len = -1;
                return ipd_rx;
            }
        }
    }
   
    _Bool esp_test(void)
    {
        uint8_t i;
        for(i=0;i<100;i++)
        {
            if(esp_inti_cmd[i][0])
            {
                if(ESP8266_SendCmd(esp_inti_cmd[i][0],esp_inti_cmd[i][1],5000))
                {
                    printf("Init:%d error\r\n",i);//失败
                }
                else
                {
                    printf("Init:%d ok\r\n",i);//成功
                }
            }
            else
            {
                printf("ESP Init Success\r\n");
                return 0;//初始化完成
            }
        }
        return 1;
    }
   
    void OneNet_FillBuf(char *buf)
    {
        char text[24];
        char buf1[128];
   
        memset(text, 0, sizeof(text));
        memset(buf1, 0, sizeof(buf1));
   
        strcpy(buf1, "{");
   
        memset(text, 0, sizeof(text));
        sprintf(text, "\"Temperature\":%f",tem);
        strcat(buf1, text);
   
        strcat(buf1, "}");
   
        sprintf(buf, "POST /devices/%s/datapoints?type=3 HTTP/1.1\r\napi-key:%s\r\nHost:api.heclouds.com\r\n"
                        "Content-Length:%d\r\n\r\n",
   
                        DEVID, APIKEY, strlen(buf1));
   
        strcat(buf, buf1);
    }
   
    //==========================================================
    //  函数名称:   OneNet_SendData
    //
    //  函数功能:   上传数据到平台
    //
    //  入口参数:   type:发送数据的格式
    //
    //  返回参数:   无
    //
    //  说明:
    //==========================================================
    void OneNet_SendData(void)
    {
   
        char buf[256];
        char buf1[50];
        memset(buf, 0, sizeof(buf));
        memset(buf1, 0, sizeof(buf1));
   
   
        OneNet_FillBuf(buf);                                    //封装数据流
        sprintf(buf1, "AT+CIPSEND=%d\r\n",strlen(buf));
        ESP8266_SendCmd(buf1,"OK",5000);
        ESP_SendString((unsigned char *)buf, strlen(buf));    //上传数据
    }


SPI读写外部FLASH

这里我用了官方的例程,所以只发应用了

/*记录上电次数*/
        SPI_Flash_Read(&count,0x0,1);
        Delay_Ms(100);
        if(!count)
            count++;
        printf("Number of power on Is: %d\r\n",count);
        count++;
        SPI_Flash_Write(&count,0,1);
        Delay_Ms(500)


TIM

我这里使用定时器主要就是做一个简单的计时,驱动也是例程写好的,直接运用了,就是用来让灯亮灭以及定时上传温度

void TIM3_IRQHandler(void)
    {
        if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查TIM3中断是否发生。
        {
            if(tim_count%2)
                GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_SET);
            else
                GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_RESET);
            tim_count++;
            TIM_ClearITPendingBit(TIM3,TIM_IT_Update);    //清除TIM3的中断挂起位。
        }
    }  


ADC

使用ADC计算内部温度,上篇已经说过,这里就不贴代码了.

MAIN

贴一下main函数

/*******************************************************************************
    * Function Name  : main
    * Description    : Main program.
    * Input          : None
    * Return         : None
    *******************************************************************************/
    int main(void)
    {
        u8 count;
   
        /*外设初始化*/
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
        Delay_Init();
        USART_Printf_Init(115200);
        USARTx_CFG();
        adc_Init();
        LED_Init();
        SPI_Flash_Init();
        TIM3_Int_Init(4999,7199);
   
   
        /*记录上电次数*/
        SPI_Flash_Read(&count,0x0,1);
        Delay_Ms(100);
        if(!count)
            count++;
        printf("Number of power on Is: %d\r\n",count);
        count++;
        SPI_Flash_Write(&count,0,1);
        Delay_Ms(500);
   
        /*初始化串口缓存结构体*/
        CLEAR_UART2();
   
        esp_test();
        while(1)
        {
            if(tim_count>50)
            {
                tim_count = 0;
                tem=get_temperature();
                printf("Temperature:%.2f\r\n",tem);
                CLEAR_UART2();
                OneNet_SendData();
            }
        }
    }


展示一下Onenet的应用



算是基本完结了吧,USB功能一直没能尝试,明天又是周一了,又开始忙碌的一周,有时间再搞(一直想玩USB功能却一直没玩,害),沁恒加油!,俺一直稀罕你支持你,国产加油!最后说一句,期待573.

再展示一个一直想玩但没时间玩的,而且已经买了,板子已经偷偷画好的579



加油,打工人,奥里给!

哎哎哎,最后附上gitee链接,主要文件我都传了上去
https://gitee.com/shihengrui/ch32-vf103





使用特权

评论回复

相关帖子

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

本版积分规则

13

主题

79

帖子

0

粉丝