目录

一 I2C协议简介

硬件I2C与软件I2C

二 代码和ATH20芯片实现温湿度的串口显示

三 用stm32f103芯片的SPI和IIC接口接上OLED屏显示中文姓名温湿度

1 先用文字字模生成器PCtolCD200生成需要的字模

2 烧录程序

四 显示温湿度

五 滚动屏显示

六 总结

七 参考文献


一 I2C协议简介

I2C 通讯协议 (Inter - Integrated Circuit) 是由 Phiilps 公司开发的,由于它引脚少,硬件实现简单, 可扩展性强,不需要 USART、CAN 等通讯协议的外部收发设备,现在被广泛地使用在系统内多 个集成电路 (IC) 间的通讯。

I2c的物理层

它的物理层有如下特点:

(1) 它是一个支持设备的总线。“总线”指多个设备共用的信号线。在一个 I2C 通讯总线中,可 连接多个 I2C 通讯设备,支持多个通讯主机及多个通讯从机。

(2) 一个 I2C 总线只使用两条总线线路,一条双向串行数据线 (SDA) ,一条串行时钟线 (SCL)。 数据线即用来表示数据,时钟线用于数据收发同步。

(3) 每个连接到总线的设备都有一个独立的地址,主机可以利用这个地址进行不同设备之间的 访问。

(4) 总线通过上拉电阻接到电源。当 I2C 设备空闲时,会输出高阻态,而当所有设备都空闲,都 输出高阻态时,由上拉电阻把总线拉成高电平。

(5) 多个主机同时使用总线时,为了防止数据冲突,会利用仲裁方式决定由哪个设备占用总线。

(6) 具有三种传输模式:标准模式传输速率为 100kbit/s ,快速模式为 400kbit/s ,高速模式下可 达 3.4Mbit/s,但目前大多 I 2C 设备尚不支持高速模式。

(7) 连接到相同总线的 IC 数量受到总线的最大电容 400pF 限制。

硬件I2C与软件I2C

硬件I2C

硬件I2C对应芯片上的I2C外设,有相应I2C驱动电路,其所使用的I2C管脚也是专用的,因而效率要远高于软件模拟的I2C;一般也较为稳定,但是程序较为繁琐。硬件(固件)I2C是直接调用内部寄存器进行配置;而软件I2C是没有寄存器这个概念的。这种方式减轻了cpu的负担。

软件I2C
软件I2C一般是使用GPIO管脚,用软件控制SCL,SDA线输出高低电平,模拟i2c协议的时序。由于直接控制 GPIO 引脚电平产生通讯时序时,需要由 CPU 控制每个时刻的引脚状态,所以称之为“软件模拟协议”方式。

二 代码和ATH20芯片实现温湿度的串口显示

在空白模板上新建一系列的c文件和h文件,然后将以下代码写上去

main.c

#include "delay.h"
#include "usart.h"
#include "bsp_i2c.h"int main(void)
{   delay_init();     //?óê±oˉêy3?ê??ˉ    uart_init(115200);     //′??ú3?ê??ˉ?a115200IIC_Init();while(1){printf("温度湿度显示");read_AHT20_once();delay_ms(1500);}
}

bsp_i2c.c

#include "bsp_i2c.h"
#include "delay.h"uint8_t   ack_status=0;
uint8_t   readByte[6];
uint8_t   AHT20_status=0;uint32_t  H1=0;  //Humility
uint32_t  T1=0;  //Temperatureuint8_t  AHT20_OutData[4];
uint8_t  AHT20sendOutData[10] = {0xFA, 0x06, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF};void IIC_Init(void)
{                        GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(    RCC_APB2Periph_GPIOB, ENABLE ); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;   //í?íìê?3?GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);IIC_SCL=1;IIC_SDA=1;}
//2úéúIIC?eê?D?o?
void IIC_Start(void)
{SDA_OUT();     //sda??ê?3?IIC_SDA=1;         IIC_SCL=1;delay_us(4);IIC_SDA=0;//START:when CLK is high,DATA change form high to low delay_us(4);IIC_SCL=0;//?ˉ×?I2C×ü??£?×?±?·¢?í?ò?óê?êy?Y
}
//2úéúIICí£?1D?o?
void IIC_Stop(void)
{SDA_OUT();//sda??ê?3?IIC_SCL=0;IIC_SDA=0;//STOP:when CLK is high DATA change form low to highdelay_us(4);IIC_SCL=1; IIC_SDA=1;//·¢?íI2C×ü???áê?D?o?delay_us(4);
}
//μè′yó|′eD?o?μ?à′
//·μ???μ£o1£??óê?ó|′e꧰ü
//        0£??óê?ó|′e3é1|
u8 IIC_Wait_Ack(void)
{u8 ucErrTime=0;SDA_IN();      //SDAéè???aê?è?  IIC_SDA=1;delay_us(1);     IIC_SCL=1;delay_us(1);    while(READ_SDA){ucErrTime++;if(ucErrTime>250){IIC_Stop();return 1;}}IIC_SCL=0;//ê±?óê?3?0      return 0;
}
//2úéúACKó|′e
void IIC_Ack(void)
{IIC_SCL=0;SDA_OUT();IIC_SDA=0;delay_us(2);IIC_SCL=1;delay_us(2);IIC_SCL=0;
}
//2?2úéúACKó|′e
void IIC_NAck(void)
{IIC_SCL=0;SDA_OUT();IIC_SDA=1;delay_us(2);IIC_SCL=1;delay_us(2);IIC_SCL=0;
}
//IIC·¢?íò???×??ú
//·μ??′ó?úóD?Tó|′e
//1£?óDó|′e
//0£??Tó|′e
void IIC_Send_Byte(u8 txd)
{                        u8 t;   SDA_OUT();         IIC_SCL=0;//à-μíê±?ó?aê?êy?Y′?ê?for(t=0;t<8;t++){              IIC_SDA=(txd&0x80)>>7;txd<<=1;      delay_us(2);   //??TEA5767?aèy???óê±??ê?±?D?μ?IIC_SCL=1;delay_us(2); IIC_SCL=0;   delay_us(2);}
}
//?á1??×??ú£?ack=1ê±£?·¢?íACK£?ack=0£?·¢?ínACK
u8 IIC_Read_Byte(unsigned char ack)
{unsigned char i,receive=0;SDA_IN();//SDAéè???aê?è?for(i=0;i<8;i++ ){IIC_SCL=0; delay_us(2);IIC_SCL=1;receive<<=1;if(READ_SDA)receive++;   delay_us(1); }                   if (!ack)IIC_NAck();//·¢?ínACKelseIIC_Ack(); //·¢?íACK   return receive;
}void IIC_WriteByte(uint16_t addr,uint8_t data,uint8_t device_addr)
{IIC_Start();  if(device_addr==0xA0) //eepromμ??·′óóú1×??úIIC_Send_Byte(0xA0 + ((addr/256)<<1));//·¢?í??μ??·elseIIC_Send_Byte(device_addr);        //·¢?÷?tμ??·IIC_Wait_Ack(); IIC_Send_Byte(addr&0xFF);   //·¢?íμíμ??·IIC_Wait_Ack(); IIC_Send_Byte(data);     //·¢?í×??ú                               IIC_Wait_Ack();                     IIC_Stop();//2úéúò???í£?1ì??t if(device_addr==0xA0) //delay_ms(10);elsedelay_us(2);
}uint16_t IIC_ReadByte(uint16_t addr,uint8_t device_addr,uint8_t ByteNumToRead)  //?á??′??÷?ò?áêy?Y
{   uint16_t data;IIC_Start();  if(device_addr==0xA0)IIC_Send_Byte(0xA0 + ((addr/256)<<1));elseIIC_Send_Byte(device_addr);    IIC_Wait_Ack();IIC_Send_Byte(addr&0xFF);   //·¢?íμíμ??·IIC_Wait_Ack(); IIC_Start();      IIC_Send_Byte(device_addr+1);       //·¢?÷?tμ??·IIC_Wait_Ack();if(ByteNumToRead == 1)//LM75???èêy?Y?a11bit{data=IIC_Read_Byte(0);}else{data=IIC_Read_Byte(1);data=(data<<8)+IIC_Read_Byte(0);}IIC_Stop();//2úéúò???í£?1ì??t     return data;
}/**********
*é???2?·??aIO?ú?£?éI2C????
*
*′ó?aò????aê??aAHT20μ?????I2C
*oˉêy??óDIICoíI2Cμ???±e£???×¢òa£?£?£?£?£?
*
*2020/2/23×?oóDT??è??ú
*
***********/
void  read_AHT20_once(void)
{delay_ms(10);reset_AHT20();delay_ms(10);init_AHT20();delay_ms(10);startMeasure_AHT20();delay_ms(80);read_AHT20();delay_ms(5);
}void  reset_AHT20(void)
{I2C_Start();I2C_WriteByte(0x70);ack_status = Receive_ACK();if(ack_status) printf("1");else printf("1-n-");I2C_WriteByte(0xBA);ack_status = Receive_ACK();if(ack_status) printf("2");else printf("2-n-");I2C_Stop();/*AHT20_OutData[0] = 0;AHT20_OutData[1] = 0;AHT20_OutData[2] = 0;AHT20_OutData[3] = 0;*/
}void  init_AHT20(void)
{I2C_Start();I2C_WriteByte(0x70);ack_status = Receive_ACK();if(ack_status) printf("3");else printf("3-n-"); I2C_WriteByte(0xE1);ack_status = Receive_ACK();if(ack_status) printf("4");else printf("4-n-");I2C_WriteByte(0x08);ack_status = Receive_ACK();if(ack_status) printf("5");else printf("5-n-");I2C_WriteByte(0x00);ack_status = Receive_ACK();if(ack_status) printf("6");else printf("6-n-");I2C_Stop();
}void  startMeasure_AHT20(void)
{//------------I2C_Start();I2C_WriteByte(0x70);ack_status = Receive_ACK();if(ack_status) printf("7");else printf("7-n-");I2C_WriteByte(0xAC);ack_status = Receive_ACK();if(ack_status) printf("8");else printf("8-n-");I2C_WriteByte(0x33);ack_status = Receive_ACK();if(ack_status) printf("9");else printf("9-n-");I2C_WriteByte(0x00);ack_status = Receive_ACK();if(ack_status) printf("10");else printf("10-n-");I2C_Stop();
}void read_AHT20(void)
{uint8_t   i;for(i=0; i<6; i++){readByte[i]=0;}//-------------I2C_Start();I2C_WriteByte(0x71);ack_status = Receive_ACK();readByte[0]= I2C_ReadByte();Send_ACK();readByte[1]= I2C_ReadByte();Send_ACK();readByte[2]= I2C_ReadByte();Send_ACK();readByte[3]= I2C_ReadByte();Send_ACK();readByte[4]= I2C_ReadByte();Send_ACK();readByte[5]= I2C_ReadByte();SendNot_Ack();//Send_ACK();I2C_Stop();//--------------if( (readByte[0] & 0x68) == 0x08 ){H1 = readByte[1];H1 = (H1<<8) | readByte[2];H1 = (H1<<8) | readByte[3];H1 = H1>>4;H1 = (H1*1000)/1024/1024;T1 = readByte[3];T1 = T1 & 0x0000000F;T1 = (T1<<8) | readByte[4];T1 = (T1<<8) | readByte[5];T1 = (T1*2000)/1024/1024 - 500;AHT20_OutData[0] = (H1>>8) & 0x000000FF;AHT20_OutData[1] = H1 & 0x000000FF;AHT20_OutData[2] = (T1>>8) & 0x000000FF;AHT20_OutData[3] = T1 & 0x000000FF;}else{AHT20_OutData[0] = 0xFF;AHT20_OutData[1] = 0xFF;AHT20_OutData[2] = 0xFF;AHT20_OutData[3] = 0xFF;printf("lyy");}printf("\r\n");printf("温度:%d%d.%d",T1/100,(T1/10)%10,T1%10);printf("湿度:%d%d.%d",H1/100,(H1/10)%10,H1%10);printf("\r\n");
}uint8_t  Receive_ACK(void)
{uint8_t result=0;uint8_t cnt=0;IIC_SCL = 0;SDA_IN(); delay_us(4);IIC_SCL = 1;delay_us(4);while(READ_SDA && (cnt<100)){cnt++;}IIC_SCL = 0;delay_us(4);if(cnt<100){result=1;}return result;
}void  Send_ACK(void)
{SDA_OUT();IIC_SCL = 0;delay_us(4);IIC_SDA = 0;delay_us(4);IIC_SCL = 1;delay_us(4);IIC_SCL = 0;delay_us(4);SDA_IN();
}void  SendNot_Ack(void)
{SDA_OUT();IIC_SCL = 0;delay_us(4);IIC_SDA = 1;delay_us(4);IIC_SCL = 1;delay_us(4);IIC_SCL = 0;delay_us(4);IIC_SDA = 0;delay_us(4);
}void I2C_WriteByte(uint8_t  input)
{uint8_t  i;SDA_OUT();for(i=0; i<8; i++){IIC_SCL = 0;delay_ms(5);if(input & 0x80){IIC_SDA = 1;//delaymm(10);}else{IIC_SDA = 0;//delaymm(10);}IIC_SCL = 1;delay_ms(5);input = (input<<1);}IIC_SCL = 0;delay_us(4);SDA_IN();delay_us(4);
}   uint8_t I2C_ReadByte(void)
{uint8_t  resultByte=0;uint8_t  i=0, a=0;IIC_SCL = 0;SDA_IN();delay_ms(4);for(i=0; i<8; i++){IIC_SCL = 1;delay_ms(3);a=0;if(READ_SDA){a=1;}else{a=0;}//resultByte = resultByte | a;resultByte = (resultByte << 1) | a;IIC_SCL = 0;delay_ms(3);}SDA_IN();delay_ms(10);return   resultByte;
}void  set_AHT20sendOutData(void)
{/* --------------------------* 0xFA 0x06 0x0A temperature(2 Bytes) humility(2Bytes) short Address(2 Bytes)* And Check (1 byte)* -------------------------*/AHT20sendOutData[3] = AHT20_OutData[0];AHT20sendOutData[4] = AHT20_OutData[1];AHT20sendOutData[5] = AHT20_OutData[2];AHT20sendOutData[6] = AHT20_OutData[3];//  AHT20sendOutData[7] = (drf1609.shortAddress >> 8) & 0x00FF;
//  AHT20sendOutData[8] = drf1609.shortAddress  & 0x00FF;// AHT20sendOutData[9] = getXY(AHT20sendOutData,10);
}void  I2C_Start(void)
{SDA_OUT();IIC_SCL = 1;delay_ms(4);IIC_SDA = 1;delay_ms(4);IIC_SDA = 0;delay_ms(4);IIC_SCL = 0;delay_ms(4);
}void  I2C_Stop(void)
{SDA_OUT();IIC_SDA = 0;delay_ms(4);IIC_SCL = 1;delay_ms(4);IIC_SDA = 1;delay_ms(4);
}

bsp_i2c.h

#ifndef __BSP_I2C_H
#define __BSP_I2C_H#include "sys.h"
#include "delay.h"
#include "usart.h"
//ê1ó?IIC1 1ò??M24C02,OLED,LM75AD,HT1382    PB6,PB7#define SDA_IN()  {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)8<<28;}
#define SDA_OUT() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)3<<28;}//IO2ù×÷oˉêy
#define IIC_SCL    PBout(6) //SCL
#define IIC_SDA    PBout(7) //SDA
#define READ_SDA   PBin(7)  //ê?è?SDA //IIC?ùóD2ù×÷oˉêy
void IIC_Init(void);                //3?ê??ˉIICμ?IO?ú
void IIC_Start(void);               //·¢?íIIC?aê?D?o?
void IIC_Stop(void);                //·¢?íIICí£?1D?o?
void IIC_Send_Byte(u8 txd);         //IIC·¢?íò???×??ú
u8 IIC_Read_Byte(unsigned char ack);//IIC?áè?ò???×??ú
u8 IIC_Wait_Ack(void);              //IICμè′yACKD?o?
void IIC_Ack(void);                 //IIC·¢?íACKD?o?
void IIC_NAck(void);                //IIC2?·¢?íACKD?o?void IIC_WriteByte(uint16_t addr,uint8_t data,uint8_t device_addr);
uint16_t IIC_ReadByte(uint16_t addr,uint8_t device_addr,uint8_t ByteNumToRead);//??′??÷μ??·£??÷?tμ??·£?òa?áμ?×??úêy  void  read_AHT20_once(void);
void  reset_AHT20(void);
void  init_AHT20(void);
void  startMeasure_AHT20(void);
void  read_AHT20(void);
uint8_t  Receive_ACK(void);
void  Send_ACK(void);
void  SendNot_Ack(void);
void I2C_WriteByte(uint8_t  input);
uint8_t I2C_ReadByte(void);
void  set_AHT20sendOutData(void);
void  I2C_Start(void);
void  I2C_Stop(void);
#endif

usart.c

#include "sys.h"
#include "usart.h"//STM32F103o?D?°?ày3ì
//?aoˉêy°?±?ày3ì
/********** mcudev.taobao.com 3??·  ********///
//è?1?ê1ó?ucos,?ò°üà¨????μ?í·???t?′?é.
#if SYSTEM_SUPPORT_UCOS
#include "includes.h"                   //ucos ê1ó?
#endif
//
//STM32?a·¢°?
//′??ú13?ê??ˉ          //     //
//?óè?ò???′ú??,?§3?printfoˉêy,??2?Dèòa????use MicroLIB
#if 1
#pragma import(__use_no_semihosting)
//±ê×??aDèòaμ??§3?oˉêy
struct __FILE
{ int handle; }; FILE __stdout;
//?¨ò?_sys_exit()ò?±ü?aê1ó?°??÷?ú?£ê?
void _sys_exit(int x)
{ x = x;
}
//???¨ò?fputcoˉêy
int fputc(int ch, FILE *f)
{      while((USART1->SR&0X40)==0);//?-?··¢?í,?±μ?·¢?ííê±?   USART1->DR = (u8) ch;      return ch;
}
#endif /*ê1ó?microLibμ?·?·¨*//*
int fputc(int ch, FILE *f)
{USART_SendData(USART1, (uint8_t) ch);while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) {}    return ch;
}
int GetKey (void)  { while (!(USART1->SR & USART_FLAG_RXNE));return ((int)(USART1->DR & 0x1FF));
}
*/#if EN_USART1_RX   //è?1?ê1?üá??óê?
//′??ú1?D??·t??3ìDò
//×¢òa,?áè?USARTx->SR?ü±ü?a?a??????μ?′í?ó
u8 USART_RX_BUF[USART_REC_LEN];     //?óê??o3?,×?′óUSART_REC_LEN??×??ú.
//?óê?×′ì?
//bit15£?    ?óê?íê3é±ê??
//bit14£?    ?óê?μ?0x0d
//bit13~0£?  ?óê?μ?μ?óDD§×??úêy??
u16 USART_RX_STA=0;       //?óê?×′ì?±ê??      void uart_init(u32 bound){//GPIO???úéè??GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //ê1?üUSART1£?GPIOAê±?ó//USART1_TX   PA.9GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;    //?′ó?í?íìê?3?GPIO_Init(GPIOA, &GPIO_InitStructure);//USART1_RX   PA.10GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//????ê?è?GPIO_Init(GPIOA, &GPIO_InitStructure);  //Usart1 NVIC ????NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//?à??ó??è??3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;      //×óó??è??3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;          //IRQí¨μàê1?üNVIC_Init(&NVIC_InitStructure);    //?ù?Y???¨μ?2?êy3?ê??ˉVIC??′??÷//USART 3?ê??ˉéè??USART_InitStructure.USART_BaudRate = bound;//ò?°?éè???a9600;USART_InitStructure.USART_WordLength = USART_WordLength_8b;//×?3¤?a8??êy?Y??ê?USART_InitStructure.USART_StopBits = USART_StopBits_1;//ò???í£?1??USART_InitStructure.USART_Parity = USART_Parity_No;//?T????D£?é??USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//?Tó2?têy?Yá÷????USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;    //ê?·¢?£ê?USART_Init(USART1, &USART_InitStructure); //3?ê??ˉ′??úUSART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//?a???D??USART_Cmd(USART1, ENABLE);                    //ê1?ü′??ú }void USART1_IRQHandler(void)                    //′??ú1?D??·t??3ìDò{u8 Res;
#ifdef OS_TICKS_PER_SEC     //è?1?ê±?ó?ú??êy?¨ò?á?,?μ?÷òaê1ó?ucosIIá?.OSIntEnter();
#endifif(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //?óê??D??(?óê?μ?μ?êy?Y±?D?ê?0x0d 0x0a?á?2){Res =USART_ReceiveData(USART1);//(USART1->DR);  //?áè??óê?μ?μ?êy?Yif((USART_RX_STA&0x8000)==0)//?óê??′íê3é{if(USART_RX_STA&0x4000)//?óê?μ?á?0x0d{if(Res!=0x0a)USART_RX_STA=0;//?óê?′í?ó,??D??aê?else USART_RX_STA|=0x8000;  //?óê?íê3éá? }else //?1??ê?μ?0X0D{  if(Res==0x0d)USART_RX_STA|=0x4000;else{USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;USART_RX_STA++;if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//?óê?êy?Y′í?ó,??D??aê??óê?      }      }}          }
#ifdef OS_TICKS_PER_SEC     //è?1?ê±?ó?ú??êy?¨ò?á?,?μ?÷òaê1ó?ucosIIá?.OSIntExit();
#endif
}
#endif  

usart.h

#ifndef __USART_H
#define __USART_H
#include "stdio.h"
#include "sys.h" //STM32F103o?D?°?ày3ì
//?aoˉêy°?±?ày3ì
/********** mcudev.taobao.com 3??·  ********///
//STM32?a·¢°?
//′??ú13?ê??ˉ          #define USART_REC_LEN            200     //?¨ò?×?′ó?óê?×??úêy 200
#define EN_USART1_RX            1           //ê1?ü£¨1£?/???1£¨0£?′??ú1?óê?extern u8  USART_RX_BUF[USART_REC_LEN]; //?óê??o3?,×?′óUSART_REC_LEN??×??ú.??×??ú?a??DD·?
extern u16 USART_RX_STA;                //?óê?×′ì?±ê??
//è?1???′??ú?D???óê?£???2?òa×¢êíò???oê?¨ò?
void uart_init(u32 bound);
#endif

delay.c

include "delay.h"
#include "sys.h"//STM32F103o?D?°?ày3ì
//?aoˉêy°?±?ày3ì
/********** mcudev.taobao.com 3??·  ********///
//è?1?ê1ó?ucos,?ò°üà¨????μ?í·???t?′?é.
#if SYSTEM_SUPPORT_UCOS
#include "includes.h"                   //ucos ê1ó?
#endif
//   //STM32?a·¢°?
//ê1ó?SysTickμ???í¨??êy?£ê????ó3ù??DD1üàí
//°üà¨delay_us,delay_ms//
static u8  fac_us=0;//us?óê±±?3?êy
static u16 fac_ms=0;//ms?óê±±?3?êy
#ifdef OS_CRITICAL_METHOD   //è?1?OS_CRITICAL_METHOD?¨ò?á?,?μ?÷ê1ó?ucosIIá?.
//systick?D??·t??oˉêy,ê1ó?ucosê±ó?μ?
void SysTick_Handler(void)
{                  OSIntEnter();        //??è??D??OSTimeTick();       //μ÷ó?ucosμ?ê±?ó·t??3ìDò               OSIntExit();        //′¥·¢è????D??èí?D??
}
#endif//3?ê??ˉ?ó3ùoˉêy
//μ±ê1ó?ucosμ?ê±oò,′?oˉêy?á3?ê??ˉucosμ?ê±?ó?ú??
//SYSTICKμ?ê±?ó1ì?¨?aHCLKê±?óμ?1/8
//SYSCLK:?μí3ê±?ó
void delay_init()
{#ifdef OS_CRITICAL_METHOD  //è?1?OS_CRITICAL_METHOD?¨ò?á?,?μ?÷ê1ó?ucosIIá?.u32 reload;
#endifSysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //????ía2?ê±?ó  HCLK/8fac_us=SystemCoreClock/8000000;   //?a?μí3ê±?óμ?1/8  #ifdef OS_CRITICAL_METHOD    //è?1?OS_CRITICAL_METHOD?¨ò?á?,?μ?÷ê1ó?ucosIIá?.reload=SystemCoreClock/8000000;     //?????óμ???êy′?êy μ¥???aK      reload*=1000000/OS_TICKS_PER_SEC;//?ù?YOS_TICKS_PER_SECéè?¨ò?3?ê±??//reload?a24????′??÷,×?′ó?μ:16777216,?ú72M??,??o?1.86s×óóò    fac_ms=1000/OS_TICKS_PER_SEC;//′ú±íucos?éò??óê±μ?×?éùμ¥??       SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;      //?a??SYSTICK?D??SysTick->LOAD=reload;   //??1/OS_TICKS_PER_SEC???D??ò?′?    SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;      //?a??SYSTICK
#elsefac_ms=(u16)fac_us*1000;//·?ucos??,′ú±í????msDèòaμ?systickê±?óêy
#endif
}                                   #ifdef OS_CRITICAL_METHOD   //ê1ó?á?ucos
//?óê±nus
//nus?aòa?óê±μ?usêy.
void delay_us(u32 nus)
{       u32 ticks;u32 told,tnow,tcnt=0;u32 reload=SysTick->LOAD; //LOADμ??μ           ticks=nus*fac_us;          //Dèòaμ??ú??êy           tcnt=0;told=SysTick->VAL;           //????è?ê±μ???êy?÷?μwhile(1){tnow=SysTick->VAL;  if(tnow!=told){     if(tnow<told)tcnt+=told-tnow;//?aà?×¢òaò???SYSTICKê?ò???μY??μ???êy?÷?í?éò?á?.else tcnt+=reload-tnow+told;     told=tnow;if(tcnt>=ticks)break;//ê±??3?1y/μèóúòa?ó3ùμ?ê±??,?òí?3?.}  };
}
//?óê±nms
//nms:òa?óê±μ?msêy
void delay_ms(u16 nms)
{   if(OSRunning==TRUE)//è?1?osò??-?ú?üá?       {         if(nms>=fac_ms)//?óê±μ?ê±??′óóúucosμ?×?éùê±???ü?ú {OSTimeDly(nms/fac_ms);//ucos?óê±}nms%=fac_ms;               //ucosò??-?T·¨ìá1??a?′D?μ??óê±á?,2éó???í¨·?ê??óê±    }delay_us((u32)(nms*1000));    //??í¨·?ê??óê±,′?ê±ucos?T·¨???ˉμ÷?è.
}
#else//2?ó?ucosê±
//?óê±nus
//nus?aòa?óê±μ?usêy.
void delay_us(u32 nus)
{       u32 temp;            SysTick->LOAD=nus*fac_us; //ê±???ó??             SysTick->VAL=0x00;        //??????êy?÷SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;          //?aê?μ1êy    do{temp=SysTick->CTRL;}while(temp&0x01&&!(temp&(1<<16)));//μè′yê±??μ?′?   SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;       //1?±???êy?÷SysTick->VAL =0X00;       //??????êy?÷
}
//?óê±nms
//×¢òanmsμ?·??§
//SysTick->LOAD?a24????′??÷,?ùò?,×?′ó?óê±?a:
//nms<=0xffffff*8*1000/SYSCLK
//SYSCLKμ¥???aHz,nmsμ¥???ams
//??72Mì??t??,nms<=1864
void delay_ms(u16 nms)
{                 u32 temp;        SysTick->LOAD=(u32)nms*fac_ms;//ê±???ó??(SysTick->LOAD?a24bit)SysTick->VAL =0x00;           //??????êy?÷SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;          //?aê?μ1êy  do{temp=SysTick->CTRL;}while(temp&0x01&&!(temp&(1<<16)));//μè′yê±??μ?′?   SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;       //1?±???êy?÷SysTick->VAL =0X00;       //??????êy?÷
}
#endif

delay.h

#ifndef __DELAY_H
#define __DELAY_H
#include "sys.h"
//   //STM32F103o?D?°?ày3ì
//?aoˉêy°?±?ày3ì
/********** mcudev.taobao.com 3??·  ********///ê1ó?SysTickμ???í¨??êy?£ê????ó3ù??DD1üàí
//°üà¨delay_us,delay_ms//
void delay_init(void);
void delay_ms(u16 nms);
void delay_us(u32 nus);#endif

sys.c

#include "sys.h"//STM32F103o?D?°?ày3ì
//?aoˉêy°?±?ày3ì
/********** mcudev.taobao.com 3??·  ********///  //STM32?a·¢°?
//?μí3?D??·?×ééè???ˉ           //********************************************************************************
void NVIC_Configuration(void)
{NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);    //éè??NVIC?D??·?×é2:2???à??ó??è??£?2???ìó|ó??è??}

sys.h

#ifndef __SYS_H
#define __SYS_H
#include "stm32f10x.h"
//   //STM32F103o?D?°?ày3ì
//?aoˉêy°?±?ày3ì
/********** mcudev.taobao.com 3??·  ********///      //0,2??§3?ucos
//1,?§3?ucos
#define SYSTEM_SUPPORT_UCOS     0       //?¨ò??μí3???t?Dê?·??§3?UCOS//??′?2ù×÷,êμ??51àà??μ?GPIO????1|?ü
//??ì?êμ??????,2???<<CM3è¨ít????>>μú????(87ò3~92ò3).
//IO?ú2ù×÷oê?¨ò?
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
#define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr))
#define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum))
//IO?úμ??·ó3é?
#define GPIOA_ODR_Addr    (GPIOA_BASE+12) //0x4001080C
#define GPIOB_ODR_Addr    (GPIOB_BASE+12) //0x40010C0C
#define GPIOC_ODR_Addr    (GPIOC_BASE+12) //0x4001100C
#define GPIOD_ODR_Addr    (GPIOD_BASE+12) //0x4001140C
#define GPIOE_ODR_Addr    (GPIOE_BASE+12) //0x4001180C
#define GPIOF_ODR_Addr    (GPIOF_BASE+12) //0x40011A0C
#define GPIOG_ODR_Addr    (GPIOG_BASE+12) //0x40011E0C    #define GPIOA_IDR_Addr    (GPIOA_BASE+8) //0x40010808
#define GPIOB_IDR_Addr    (GPIOB_BASE+8) //0x40010C08
#define GPIOC_IDR_Addr    (GPIOC_BASE+8) //0x40011008
#define GPIOD_IDR_Addr    (GPIOD_BASE+8) //0x40011408
#define GPIOE_IDR_Addr    (GPIOE_BASE+8) //0x40011808
#define GPIOF_IDR_Addr    (GPIOF_BASE+8) //0x40011A08
#define GPIOG_IDR_Addr    (GPIOG_BASE+8) //0x40011E08 //IO?ú2ù×÷,????μ¥ò?μ?IO?ú!
//è·±£nμ??μD?óú16!
#define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)  //ê?3?
#define PAin(n)    BIT_ADDR(GPIOA_IDR_Addr,n)  //ê?è? #define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr,n)  //ê?3?
#define PBin(n)    BIT_ADDR(GPIOB_IDR_Addr,n)  //ê?è? #define PCout(n)   BIT_ADDR(GPIOC_ODR_Addr,n)  //ê?3?
#define PCin(n)    BIT_ADDR(GPIOC_IDR_Addr,n)  //ê?è? #define PDout(n)   BIT_ADDR(GPIOD_ODR_Addr,n)  //ê?3?
#define PDin(n)    BIT_ADDR(GPIOD_IDR_Addr,n)  //ê?è? #define PEout(n)   BIT_ADDR(GPIOE_ODR_Addr,n)  //ê?3?
#define PEin(n)    BIT_ADDR(GPIOE_IDR_Addr,n)  //ê?è?#define PFout(n)   BIT_ADDR(GPIOF_ODR_Addr,n)  //ê?3?
#define PFin(n)    BIT_ADDR(GPIOF_IDR_Addr,n)  //ê?è?#define PGout(n)   BIT_ADDR(GPIOG_ODR_Addr,n)  //ê?3?
#define PGin(n)    BIT_ADDR(GPIOG_IDR_Addr,n)  //ê?è?void NVIC_Configuration(void);#endif

然后将上述.c的源文件加入同一个工程文件里面构建。

然后将上述构建出来的HEX文件烧入芯片,

然后将STM32F103芯片的PB6接口接到AHT20芯片的SCL口,PA7口接相应的SDA口,然后3.3V对接,接地对接后,用USB转TTL与芯片链接接到电脑上,并且打开电脑的串口助手,打开串口,然后每隔几秒得到一组温度和湿度的数据。

在上述得到一系列的21.8摄氏度的情况下,用手指去捏着AHT20后可以得到明显温度和湿度都得到大幅度的上升,得出有效的温度传感器。

三 用stm32f103芯片的SPI和IIC接口接上OLED屏显示中文姓名温湿度

首先用以下载的文件后打开其中的工程文件,可以得到其中的所有源代码文件,将其中代码中的一些内容进行更改就可以得到我们需要的内容。

1 先用文字字模生成器PCtolCD200生成需要的字模

由于OLED显示屏是竖屏幕显示所以需要横屏显示的时候就需要旋转90度这里特意将小字转换与其他字体方向相反试试

然后在将以上得到的字模复制到工程文件里面的gui.c里面的oledfond.h文件里面的相应字模模块

然后进入test.c中将修改显示函数void TEST_MainPage(void)中的原内容中的名字和学号更改为自己的就可以了

在将main.c中的while循环语句中的第一项不更改其他的全部加上注释或者删除均可如下

2 烧录程序

做完上述步骤后,构建完毕生成hex文件,将此Hex文件烧录到自己的芯片当中,然后以一定接法以oled屏和stm32芯片相接,具体如下

OLED      to       stm32

VCC                   3.3V

GND                   GND

D0                       PB13

D1                      PB15

DC                      PB10

CS                       PB11

RES                    PB12

然后给芯片供电,OLED屏亮起来得到以下内容

可以看到成功显示了名字和学号,小字也得到了相应的翻转。

四 显示温湿度

显示温湿度也需要有文字的显示,所以和以上一样,首先点开工程文件里面的test.c分支里面的oldefond.h头文件里面,将里面16*16的点阵中的内容改一下,改成当前温湿度的字模。当然 也是需要翻转的

因为需要用到温湿度检测,所以需要用到最上面的温湿度检测代码,以及需要用到AHT20芯片,所以需要将温度湿度检测工程里面的bsp_i2c.c,bsp_i2c.h,sys.c,sys.h移植到本工程文件里面,当然sys可能会冲突,所以最好改名为AHT20_sys.c和AHT20_sys.h.然后在将bsp_i2c.c中的代码中的串口发送改为OLDE显示,需要更改一些代码如下void show_oled (void)

void shwo_oled(void)
{
GUI_ShowCHinese(28,10,16,"当前温湿度",1);GUI_ShowCHinese(20,32,16,"温度:",1);GUI_ShowString(60,32,strTemp1,16,1);GUI_ShowString(68,32,strTemp2,16,1);GUI_ShowString(76,32,".",16,1);GUI_ShowString(84,32,strTemp3,16,1);GUI_ShowCHinese(92,32,16,"℃",1);GUI_ShowCHinese(20,48,16,"湿度:",1);GUI_ShowString(60,48,strHumi1,16,1);GUI_ShowString(68,48,strHumi2,16,1);GUI_ShowString(76,48,".",16,1);GUI_ShowString(84,48,strHumi3,16,1);GUI_ShowCHinese(92,48,16,"%",1);
}

然后在将main.c主函数中的不需要用到的滚动等函数注释掉或者删掉,然后加上以下代码

现在就大功告成可以开始构建了然后将生成的hex文件烧录到芯片里面,然后在芯片上同时接上oled显示屏和AHT20就可以了,在OLED屏幕上进行温湿度的显示

如上,显示了温湿度,并且用手指触碰AHT20温湿度感应上时其温湿度就会上升,得出所需要的结果。

五 滚动屏显示

和以上相似,先将需要滚动显示的文字加载gui.c中的oledfond.h中的16*16的文字点阵中,

然后将test.c中void TEST_MainPage(void)函数下的显示中文函数语句打上其他的可以删除可以加以注释

然后将main.c中的主函数中的while循环删除或者注释掉,然后在其下面加入新的滚动函数

OLED_WR_Byte(0x2E,OLED_CMD);        //关闭滚动OLED_WR_Byte(0x27,OLED_CMD);        //水平向左或者右滚动 26/27OLED_WR_Byte(0x00,OLED_CMD);        //虚拟字节OLED_WR_Byte(0x00,OLED_CMD);        //起始页 0OLED_WR_Byte(0x07,OLED_CMD);        //滚动时间间隔OLED_WR_Byte(0x07,OLED_CMD);        //终止页 7OLED_WR_Byte(0x00,OLED_CMD);        //虚拟字节OLED_WR_Byte(0xFF,OLED_CMD);        //虚拟字节TEST_MainPage();OLED_WR_Byte(0x2F,OLED_CMD);        //开启滚动

然后构建生成HEX文件,将文件烧录到芯片中。

stm32f103芯片和OLED屏的接法如上就可以得到如下所示的滚动字幕

得到以上滚动显示的“白日依山尽”

六 总结

本次使用了SPI和i2c分别显示温湿度和使用中文字模生成器生成字模OLDE屏幕上显示了文字,也将温湿度从串口上搬到了OLED屏幕上,得到了滚屏显示等的结果,但上面实现的就只有代码的修改,文字的修改,其实还需要学习的内容还有很多,加油吧。

七 参考文献

基于 SPI 协议用 0.96 寸 OLED 显示汉字及温湿度数据_L-GRAZY的博客-CSDN博客

https://doc.embedfire.com/mcu/stm32/f407batianhu/hal/pdf/[%E9%87%8E%E7%81%ABEmbedFire]%E3%80%8ASTM32%20HAL%E5%BA%93%E5%BC%80%E5%8F%91%E5%AE%9E%E6%88%98%E6%8C%87%E5%8D%97%E2%80%94%E2%80%94%E5%9F%BA%E4%BA%8E%E9%87%8E%E7%81%AB%E9%9C%B8%E5%A4%A9%E8%99%8E%E5%BC%80%E5%8F%91%E6%9D%BF%E3%80%8B.pdf

用STM32F103达成基于I2C协议的AHT20温湿度传感器和OLED屏显示汉字相关推荐

  1. STM32F103完成基于I2C协议的AHT20温湿度传感器的数据采集

    文章目录 一.I2C总线通讯协议 1.I2C总线简介 2.I2C 协议的物理层和协议层 2.1物理层 2.2协议层 3.I2C的两种方式--硬件I2C和软件I2C 3.1硬件I2C 3.2软件I2C ...

  2. STM32F103完成基于I2C协议的AHT20温湿度传感器的数据采集,并将采集的温度-湿度值通过串口输出

    文章目录 前言 一.I2C总线通信协议 1.I2C总线 2.工作原理 3.I2C特点 4.I2C模式选择 5.软件I2C和硬件I2C 二.串口输出温湿度传感器的数据 1.核心代码分析 2.硬件实操连接 ...

  3. STM32F103完成基于I2C协议的AHT20温湿度传感器数据采集

    目录 一.I2C总线协议 二.实现AHT20采集程序 三.总结 一.I2C总线协议 1.什么是I2C总线? I2C总线是由Philips公司开发的一种简单.双向二线制同步串行总线.它只需要两根线即可在 ...

  4. STM32F103基于I2C协议的AHT20温湿度传感器的数据采集

    目录 一.I2C 1.I2C 协议简介 2.I2C 物理层 3.协议层 通讯的起始和停止信号 数据有效性 响应 4. 软件I2C"和"硬件I2C 二.实现AHT20采集程序 1.A ...

  5. 基于I2C协议的AHT20温湿度传感器的数据采集

    文章目录 一.I2C相关 1.I2C总线简介 工作原理 总线特征 2.I2C协议简介 软件I2C 硬件I2C 二者比较 二.基于I2C的AHT20温湿度采集实验 AHT20简介 1.实验要求 2.实验 ...

  6. 基于I2C/SPI总线的温湿度采集与OLED显示

    实验一 实验目的 学习I2C总线通信协议,使用STM32F103完成基于I2C协议的AHT20温湿度传感器的数据采集,并将采集的温度-湿度值通过串口输出.具体任务: 1)解释什么是"软件I2 ...

  7. 基于I2C硬件协议的AHT20温湿度传感器的数据采集

    基于I2C的温湿度采集 硬件I2C和软件I2C 温湿度采集 任务要求 硬件连接 添加代码 最终效果 硬件I2C和软件I2C 硬件I2C对应芯片上的baiI2C外设,有相应I2C驱动电路,其所使用的I2 ...

  8. AHT20温湿度传感器的数据采集

    目录 一.AHT20温度传感器数据采集 1.目的 2.准备条件 3.1实现代码 3.2连接器件 3.3编译烧录 3.4运行结果 二.OLED屏显和汉字点阵编码 1.目的 使用STM32F103的SPI ...

  9. 基于I2C协议利用STM32进行温湿度传感器的数据采集

    目录 一.I2C总线通信协议的介绍 1.I2C简介 2.I2C总线时序图 3.五种速率 4.四种信号 5.I2C的优缺点 6.软件IIC和硬件IIC 二.创建工程 1.实验目的 2.工具的选择 3.相 ...

最新文章

  1. c# 逆转数组元素的排序
  2. centos + php+ unixodbc + FreeTDS 配置
  3. [HDOJ4006]The kth great number
  4. 迷宫寻宝(一) ---- 状态压缩
  5. 初学者的编程自学指南
  6. shiro学习(23):动态添加验证规则3
  7. 学习笔记25_MVC前台API
  8. (44)FPGA条件编译(选择语句)
  9. jQuery源码分析系列:.domManip() .buildFragment() .clean()
  10. 天猫魔盒android开发者模式,【当贝市场】天猫魔盒M16S开启远程调试模式教程
  11. 英语在线听力翻译器_英语听力翻译软件下载_英语听力翻译2020官网下载地址_开心技术乐园...
  12. mid、mif文件操作工具类
  13. 计算机系统运行费,关于同意计算机离港系统实行收费的批复
  14. 20190301 小中大
  15. C语言/c++:实验报错[Error] ld returned 1 exit status的解决方案
  16. Ps做的图片html显示不了,为什么导入到PS的图片有图层却显示不出来?
  17. 2021年秋招面经分享·平头哥【芯片设计/验证/DFT工程师】
  18. 嘘!市面上短视频(douyin)“去水印”的工具原来是这样实现的
  19. 黑马程序员————IO流3(day20)
  20. 火鸟门户v4.0 2019全能地方门户系统源码

热门文章

  1. Android 动画介绍及自定义3D动画效果的基本使用
  2. VMware虚拟机不能联网终极大招
  3. Tessellation Shader(细分曲面着色器)
  4. linux搭建百度离线地图服务器地址,BIGEMAP离线地图服务器(开发版)
  5. 青岛职业技术学院计算机专业录取分数线,2017年青岛市中职技校录取分数线公布...
  6. Typora+PicGo图床配置(超详步骤教学)
  7. WHEA-Logger 17错误:发生了已更正的硬件错误
  8. [Vue warn]: Error in v-on handler: “ReferenceError: addForm is not defined“
  9. Python: PS 滤镜--高反差保留 (High pass)
  10. 3-11 网卡绑定bond0的实现