色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

聚豐項目 > 基于CH32V103的體溫檢測儀

基于CH32V103的體溫檢測儀

本項目基于沁恒RISC-V架構的CH32V103,通過驅動ADT7320,實現了一個簡單的體溫檢測,通過ADT7320接觸人體表面,OLED屏幕顯示出來。

懶得搭理世間煩擾 懶得搭理世間煩擾

分享
0 喜歡這個項目
團隊介紹

懶得搭理世間煩擾 懶得搭理世間煩擾

團隊成員

石文強

分享
項目簡介
本項目基于沁恒RISC-V架構的CH32V103,通過驅動ADT7320,實現了一個簡單的體溫檢測,通過ADT7320接觸人體表面,OLED屏幕顯示出來。
硬件說明

H32V103R8T6最高80MHz系統主頻 ,片上集成 RAM 20K, Flash 64K,UART、IIC 、SPI、ADC、PWM、USB等資源?;贛ounRiver Studio(MRS) 可使用RT-Thread nano進行開發。

ADT7320是一款4 mm × 4 mm LFCSP封裝高精度數字溫度傳感器,可在較寬的工業溫度范圍內提供突破性的性能。它內置一個帶隙溫度基準源, 一個溫度傳感器和一個16位模數轉換器(ADC),用來監控溫度并進行數字轉換,分辨率為0.0078°C。默認ADC分辨率設置為13位(0.0625°C)。ADC分辨率為用戶可編程模式,可通過串行接口更改。

特性

高性能

溫度精度:

±0.2°C(?10°C+85°C, 3 V~3.3V)

±0.25°C(?20°C+105°C, 3V~3.6V)

16位溫度分辨率:0.0078°C

超低溫漂:0.0073°C

NIST可溯源或相當功能

6 ms快速首次上電溫度轉換

易于實現

用戶無需溫度校準/校正

無需線性校正

低功耗

1 SPS(每秒采樣率)省電模式

正常模式:700 μW(典型值,3.3 V)

關斷模式:7 μW(典型值,3.3 V)

寬工作范圍

溫度范圍:?40°C+150

電壓范圍:2.7 V5.5 V

可編程中斷

臨界過溫中斷

過溫/欠溫中斷

SPI兼容型接口

16引腳、4 mm × 4 mm LFCSP封裝,符合RoHS標準


下圖是ADT7320的原理圖

FsgBzCg1PZ98UzeprMsBENxcVXE9

軟件說明

OLED的驅動代碼

#include "oled.h"

#include "oledfont.h"


u8 OLED_GRAM[144][8];


//反顯函數

void OLED_ColorTurn(u8 i)

{

    if(i==0)

        {

            OLED_WR_Byte(0xA6,OLED_CMD);//正常顯示

        }

    if(i==1)

        {

            OLED_WR_Byte(0xA7,OLED_CMD);//反色顯示

        }

}


//屏幕旋轉180度

void OLED_DisplayTurn(u8 i)

{

    if(i==0)

        {

            OLED_WR_Byte(0xC8,OLED_CMD);//正常顯示

            OLED_WR_Byte(0xA1,OLED_CMD);

        }

    if(i==1)

        {

            OLED_WR_Byte(0xC0,OLED_CMD);//反轉顯示

            OLED_WR_Byte(0xA0,OLED_CMD);

        }

}



void OLED_WR_Byte(u8 dat,u8 cmd)

{

    u8 i;

    if(cmd)

      OLED_DC_Set();

    else

      OLED_DC_Clr();

    OLED_CS_Clr();

    for(i=0;i<8;i++)

    {

        OLED_SCLK_Clr();

        if(dat&0x80)

           OLED_SDIN_Set();

        else

           OLED_SDIN_Clr();

        OLED_SCLK_Set();

        dat<<=1;

    }

    OLED_CS_Set();

    OLED_DC_Set();

}


//開啟OLED顯示

void OLED_DisPlay_On(void)

{

    OLED_WR_Byte(0x8D,OLED_CMD);//電荷泵使能

    OLED_WR_Byte(0x14,OLED_CMD);//開啟電荷泵

    OLED_WR_Byte(0xAF,OLED_CMD);//點亮屏幕

}


//關閉OLED顯示

void OLED_DisPlay_Off(void)

{

    OLED_WR_Byte(0x8D,OLED_CMD);//電荷泵使能

    OLED_WR_Byte(0x10,OLED_CMD);//關閉電荷泵

    OLED_WR_Byte(0xAF,OLED_CMD);//關閉屏幕

}


//更新顯存到OLED

void OLED_Refresh(void)

{

    u8 i,n;

    for(i=0;i<8;i++)

    {

       OLED_WR_Byte(0xb0+i,OLED_CMD); //設置行起始地址

       OLED_WR_Byte(0x00,OLED_CMD);   //設置低列起始地址

       OLED_WR_Byte(0x10,OLED_CMD);   //設置高列起始地址

       for(n=0;n<128;n++)

         OLED_WR_Byte(OLED_GRAM[n][i],OLED_DATA);

  }

}

//清屏函數

void OLED_Clear(void)

{

    u8 i,n;

    for(i=0;i<8;i++)

    {

       for(n=0;n<128;n++)

            {

             OLED_GRAM[n][i]=0;//清除所有數據

            }

  }

    OLED_Refresh();//更新顯示

}


//畫點

//x:0~127

//y:0~63

void OLED_DrawPoint(u8 x,u8 y)

{

    u8 i,m,n;

    i=y/8;

    m=y%8;

    n=1<<m;

    OLED_GRAM[x][i]|=n;

}


//清除一個點

//x:0~127

//y:0~63

void OLED_ClearPoint(u8 x,u8 y)

{

    u8 i,m,n;

    i=y/8;

    m=y%8;

    n=1<<m;

    OLED_GRAM[x][i]=~OLED_GRAM[x][i];

    OLED_GRAM[x][i]|=n;

    OLED_GRAM[x][i]=~OLED_GRAM[x][i];

}



//畫線

//x:0~128

//y:0~64

void OLED_DrawLine(u8 x1,u8 y1,u8 x2,u8 y2)

{

    u8 i,k,k1,k2;

    if((x1<0)||(x2>128)||(y1<0)||(y2>64)||(x1>x2)||(y1>y2))return;

    if(x1==x2)    //畫豎線

    {

            for(i=0;i<(y2-y1);i++)

            {

                OLED_DrawPoint(x1,y1+i);

            }

  }

    else if(y1==y2)   //畫橫線

    {

            for(i=0;i<(x2-x1);i++)

            {

                OLED_DrawPoint(x1+i,y1);

            }

  }

    else      //畫斜線

    {

        k1=y2-y1;

        k2=x2-x1;

        k=k1*10/k2;

        for(i=0;i<(x2-x1);i++)

            {

              OLED_DrawPoint(x1+i,y1+i*k/10);

            }

    }

}

//x,y:圓心坐標

//r:圓的半徑

void OLED_DrawCircle(u8 x,u8 y,u8 r)

{

    int a, b,num;

    a = 0;

    b = r;

    while(2 * b * b >= r * r)

    {

        OLED_DrawPoint(x + a, y - b);

        OLED_DrawPoint(x - a, y - b);

        OLED_DrawPoint(x - a, y + b);

        OLED_DrawPoint(x + a, y + b);


        OLED_DrawPoint(x + b, y + a);

        OLED_DrawPoint(x + b, y - a);

        OLED_DrawPoint(x - b, y - a);

        OLED_DrawPoint(x - b, y + a);


        a++;

        num = (a * a + b * b) - r*r;//計算畫的點離圓心的距離

        if(num > 0)

        {

            b--;

            a--;

        }

    }

}




//在指定位置顯示一個字符,包括部分字符

//x:0~127

//y:0~63

//size:選擇字體 12/16/24

//取模方式 逐列式

void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size1)

{

    u8 i,m,temp,size2,chr1;

    u8 y0=y;

    size2=(size1/8+((size1%8)?1:0))*(size1/2);  //得到字體一個字符對應點陣集所占的字節數

    chr1=chr-' ';  //計算偏移后的值

    for(i=0;i<size2;i++)

    {

        if(size1==12)

        {temp=asc2_1206[chr1][i];} //調用1206字體

        else if(size1==16)

        {temp=asc2_1608[chr1][i];} //調用1608字體

        else if(size1==24)

        {temp=asc2_2412[chr1][i];} //調用2412字體

        else return;

                for(m=0;m<8;m++)           //寫入數據

                {

                    if(temp&0x80)OLED_DrawPoint(x,y);

                    else OLED_ClearPoint(x,y);

                    temp<<=1;

                    y++;

                    if((y-y0)==size1)

                    {

                        y=y0;

                        x++;

                        break;

          }

                }

  }

}



//顯示字符串

//x,y:起點坐標

//size1:字體大小

//*chr:字符串起始地址

void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 size1)

{

    while((*chr>=' ')&&(*chr<='~'))//判斷是不是非法字符!

    {

        OLED_ShowChar(x,y,*chr,size1);

        x+=size1/2;

        if(x>128-size1)  //換行

        {

            x=0;

            y+=2;

    }

        chr++;

  }

}


//m^n

u32 OLED_Pow(u8 m,u8 n)

{

    u32 result=1;

    while(n--)

    {

      result*=m;

    }

    return result;

}


////顯示2個數字

////x,y :起點坐標

////len :數字的位數

////size:字體大小

void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size1)

{

    u8 t,temp;

    for(t=0;t<len;t++)

    {

        temp=(num/OLED_Pow(10,len-t-1))%10;

            if(temp==0)

            {

                OLED_ShowChar(x+(size1/2)*t,y,'0',size1);

      }

            else

            {

              OLED_ShowChar(x+(size1/2)*t,y,temp+'0',size1);

            }

  }

}


//顯示漢字

//x,y:起點坐標

//num:漢字對應的序號

//取模方式 列行式

void OLED_ShowChinese(u8 x,u8 y,u8 num,u8 size1)

{

    u8 i,m,n=0,temp,chr1;

    u8 x0=x,y0=y;

    u8 size3=size1/8;

    while(size3--)

    {

        chr1=num*size1/8+n;

        n++;

            for(i=0;i<size1;i++)

            {

                if(size1==16)

                        {temp=Hzk1[chr1][i];}//調用16*16字體

                else if(size1==24)

                        {temp=Hzk2[chr1][i];}//調用24*24字體

                else if(size1==32)

                        {temp=Hzk3[chr1][i];}//調用32*32字體

                else if(size1==64)

                        {temp=Hzk4[chr1][i];}//調用64*64字體

                else return;


                        for(m=0;m<8;m++)

                            {

                                if(temp&0x01)OLED_DrawPoint(x,y);

                                else OLED_ClearPoint(x,y);

                                temp>>=1;

                                y++;

                            }

                            x++;

                            if((x-x0)==size1)

                            {x=x0;y0=y0+8;}

                            y=y0;

             }

    }

}


//num 顯示漢字的個數

//space 每一遍顯示的間隔

void OLED_ScrollDisplay(u8 num,u8 space)

{

    u8 i,n,t=0,m=0,r;

    while(1)

    {

        if(m==0)

        {

        OLED_ShowChinese(128,24,t,16); //寫入一個漢字保存在OLED_GRAM[][]數組中

            t++;

        }

        if(t==num)

            {

                for(r=0;r<16*space;r++)      //顯示間隔

                 {

                    for(i=0;i<144;i++)

                        {

                            for(n=0;n<8;n++)

                            {

                                OLED_GRAM[i-1][n]=OLED_GRAM[i][n];

                            }

                        }

           OLED_Refresh();

                 }

        t=0;

      }

        m++;

        if(m==16){m=0;}

        for(i=0;i<144;i++)   //實現左移

        {

            for(n=0;n<8;n++)

            {

                OLED_GRAM[i-1][n]=OLED_GRAM[i][n];

            }

        }

        OLED_Refresh();

    }

}


//配置寫入數據的起始位置

void OLED_WR_BP(u8 x,u8 y)

{

    OLED_WR_Byte(0xb0+y,OLED_CMD);//設置行起始地址

    OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);

    OLED_WR_Byte((x&0x0f),OLED_CMD);

}


//x0,y0:起點坐標

//x1,y1:終點坐標

//BMP[]:要寫入的圖片數組

void OLED_ShowPicture(u8 x0,u8 y0,u8 x1,u8 y1,u8 BMP[])

{

    u32 j=0;

    u8 x=0,y=0;

    if(y%8==0)y=0;

    else y+=1;

    for(y=y0;y<y1;y++)

     {

         OLED_WR_BP(x0,y);

         for(x=x0;x<x1;x++)

         {

             OLED_WR_Byte(BMP[j],OLED_DATA);

             j++;

     }

     }

}

//OLED的初始化

void OLED_Init(void)

{

    GPIO_InitTypeDef  GPIO_InitStructure;


    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);    //使能A端口時鐘

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;         //推挽輸出

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz

    GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_SetBits(GPIOA,GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5);


    OLED_RST_Clr();//復位

    Delay_Ms(200);

    OLED_RST_Set();


    OLED_WR_Byte(0xAE,OLED_CMD);//--turn off oled panel

    OLED_WR_Byte(0x00,OLED_CMD);//---set low column address

    OLED_WR_Byte(0x10,OLED_CMD);//---set high column address

    OLED_WR_Byte(0x40,OLED_CMD);//--set start line address  Set Mapping RAM Display Start Line (0x00~0x3F)

    OLED_WR_Byte(0x81,OLED_CMD);//--set contrast control register

    OLED_WR_Byte(0xCF,OLED_CMD);// Set SEG Output Current Brightness

    OLED_WR_Byte(0xA1,OLED_CMD);//--Set SEG/Column Mapping     0xa0左右反置 0xa1正常

    OLED_WR_Byte(0xC8,OLED_CMD);//Set COM/Row Scan Direction   0xc0上下反置 0xc8正常

    OLED_WR_Byte(0xA6,OLED_CMD);//--set normal display

    OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)

    OLED_WR_Byte(0x3f,OLED_CMD);//--1/64 duty

    OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset   Shift Mapping RAM Counter (0x00~0x3F)

    OLED_WR_Byte(0x00,OLED_CMD);//-not offset

    OLED_WR_Byte(0xd5,OLED_CMD);//--set display clock divide ratio/oscillator frequency

    OLED_WR_Byte(0x80,OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec

    OLED_WR_Byte(0xD9,OLED_CMD);//--set pre-charge period

    OLED_WR_Byte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock

    OLED_WR_Byte(0xDA,OLED_CMD);//--set com pins hardware configuration

    OLED_WR_Byte(0x12,OLED_CMD);

    OLED_WR_Byte(0xDB,OLED_CMD);//--set vcomh

    OLED_WR_Byte(0x40,OLED_CMD);//Set VCOM Deselect Level

    OLED_WR_Byte(0x20,OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02)

    OLED_WR_Byte(0x02,OLED_CMD);//

    OLED_WR_Byte(0x8D,OLED_CMD);//--set Charge Pump enable/disable

    OLED_WR_Byte(0x14,OLED_CMD);//--set(0x10) disable

    OLED_WR_Byte(0xA4,OLED_CMD);// Disable Entire Display On (0xa4/0xa5)

    OLED_WR_Byte(0xA6,OLED_CMD);// Disable Inverse Display On (0xa6/a7)

    OLED_WR_Byte(0xAF,OLED_CMD);

    OLED_Clear();

}

ADT7320的驅動代碼(該代碼是基于在官方的代碼上修改的)

/********************************************************************************

 Function:   ReadFromADT7320ViaSPI

 Parameter:  none

 Return value :  unsigned int

 Description :  Configure the regisiters of ADT7320, and read the convention data.

********************************************************************************/

#include "adt7320.h"


void ADT7320_Init(void){

    GPIO_InitTypeDef  GPIO_InitStructure;


    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);    //使能A端口時鐘

    GPIO_InitStructure.GPIO_Pin = GPIO_ADT7320_DIN | GPOI_ADT7320_SCL | GPOI_ADT7320_CS;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;         //推挽輸出

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz

    GPIO_Init(GPIOA, &GPIO_InitStructure);


    GPIO_InitStructure.GPIO_Pin = GPOI_ADT7320_DOUT;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;         //推挽輸出

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz

    GPIO_Init(GPIOA, &GPIO_InitStructure);


    GPIO_SetBits(GPIOA,GPIO_ADT7320_DIN | GPOI_ADT7320_SCL | GPOI_ADT7320_CS);


}


unsigned int ReadFromADT7320ViaSPI(unsigned int reg_address, unsigned int Bit)

{

    unsigned int   i;

    unsigned int misoValue = 0;

    unsigned int spi_Value;

    //unsigned int flag;

    spi_Value = (0x40 | ( 0x78 & (reg_address << 3)));


    //flag = spi_Value;

    CS_1;//ADuC7026OutputBit(CS,1);

    SCL_1;//ADuC7026OutputBit(SCL,1);

    CS_0;//ADuC7026OutputBit(CS,0);

    Delay_Ms(5);//HAL_Delay(5);


    for(i=0;i<8;i++)

    {

    SCL_0   ;//ADuC7026OutputBit(SCL,0);

        if(spi_Value & 0x80)

            DIN_1;//ADuC7026OutputBit(DIN,1);

        else

            DIN_0;//ADuC7026OutputBit(DIN,0);

        Delay_Ms(5);//HAL_Delay(5);

        SCL_1;//ADuC7026OutputBit(SCL,1);

        spi_Value = (spi_Value << 1);

        Delay_Ms(5);//HAL_Delay(5);

    }

    DIN_1;

  //ADuC7026Delay(50);

    for(i=0;i<Bit;i++)

    {

    SCL_0;//ADuC7026OutputBit(SCL,0);

    misoValue = (misoValue << 1);

    Delay_Ms(10);//HAL_Delay(10);

        if((DOUT) == 1)

            misoValue |= 0x0001;

    else  {

        misoValue &= 0xfffe;

    }


        Delay_Ms(2);//HAL_Delay(2);

        SCL_1;//ADuC7026OutputBit(SCL,1);


        Delay_Ms(8);//HAL_Delay(8);

    }

    SCL_1;//ADuC7026OutputBit(SCL,1);

    CS_1;//ADuC7026OutputBit(CS,1);

    return  misoValue;

}


/********************************************************************************

 Function:   WriteToADT7320ViaSPI

 Parameter:  unsigned char spi_mosiValue

 Return value :  none

 Description :  Configure the regisiters of ADT7320, and read the convention data.

********************************************************************************/

void WriteToADT7320ViaSPI(unsigned int reg_address, unsigned int reg_data, unsigned int Bit)

{

    unsigned int   i;

    unsigned int spi_Value;

    unsigned int spi_Value_data;

    spi_Value = ( 0x78 & (reg_address << 3));

    spi_Value_data = reg_data;


    CS_1;//ADuC7026OutputBit(CS,1);

    SCL_1;//ADuC7026OutputBit(SCL,1);

    CS_0;//ADuC7026OutputBit(CS,0);


    for(i=0;i<8;i++)

    {

    SCL_0;//ADuC7026OutputBit(SCL,0);

        if(spi_Value & 0x80)

            DIN_1;//ADuC7026OutputBit(DIN,1);

        else

            DIN_0;//ADuC7026OutputBit(DIN,0);

        Delay_Ms(2);//          HAL_Delay(2);

        SCL_1;//ADuC7026OutputBit(SCL,1);

    spi_Value = (spi_Value << 1);

    Delay_Ms(5);//HAL_Delay(5);

    }


    if(Bit == 8)

    {

        for(i=0;i<Bit;i++)

        {

                SCL_0;//ADuC7026OutputBit(SCL,0);

                if((spi_Value_data & 0x80)==0x80)

                    DIN_1;//ADuC7026OutputBit(DIN,1);

                else

                    DIN_0;//ADuC7026OutputBit(DIN,0);

                Delay_Ms(2);//HAL_Delay(2);

            SCL_1;//ADuC7026OutputBit(SCL,1);

            spi_Value_data = (spi_Value_data << 1);

            Delay_Ms(5);//HAL_Delay(5);

        }

    }else{

        for(i=0;i<Bit;i++)

        {

                SCL_0;//ADuC7026OutputBit(SCL,0);

                if(spi_Value_data & 0x8000)

                    DIN_1;//ADuC7026OutputBit(DIN,1);

                else

                    DIN_0;//ADuC7026OutputBit(DIN,0);

                Delay_Ms(2);//HAL_Delay(2);

            SCL_1;//ADuC7026OutputBit(SCL,1);

            spi_Value_data = (spi_Value_data << 1);

            Delay_Ms(5);//HAL_Delay(5);

        }

    }

    SCL_1;//ADuC7026OutputBit(SCL,1);

    CS_1;//ADuC7026OutputBit(CS,1);

}


附件

(0.53 MB)下載

評論區(0 )
主站蜘蛛池模板: 日本综艺大尺度无删减版在线| 亚洲爆乳少妇精品无码专区| 国产亚洲精品99一区二区| 与邻居换娶妻子2在线观看| 人与畜禽CROPROATION免费| 国产一区二区波多野结衣| 诱咪youmiss| 小黄文纯肉污到你湿| 日本漫画无彩翼漫画| 精品一二三区久久AAA片| 丰满少妇被猛烈进出69影院| 在线 | 果冻国产传媒61国产免费 在镜头里被CAO翻了H | 99久久国产综合精品| 亚洲99精品A片久久久久久| 人与畜禽CROPROATION免费| 美女夫妻内射潮视频| 饥渴的40岁熟妇完整版在线| 国产成人99久久亚洲综合精品| 99久久99久久久精品齐齐鬼色| 亚洲裸舞 hd| 天堂在线亚洲精品专区| 日本熟妇乱妇熟色A片蜜桃亚洲| 麻豆国产自制在线观看| 久久久久久91香蕉国产| 国语对白嫖老妇胖老太| 国产精品亚洲专一区二区三区| 俄罗斯人与动ZOZ0| 饱满奶大30p| XXX老姥群交| YY600800新视觉理论私人| 97草碰在线视频免费| 5g天天奭视频| 重口味av| 91热久久免费频精品99欧美| 最近中文字幕2019免费版日本| 印度人XXx| 在线免费观看a视频| 最近的2019中文字幕国语完整版| 野花社区视频WWW高清| 亚洲另类欧美综合在线| 亚洲欧美色综合影院|