[AT32L021] 【AT-START-L021测评】+ SPI驱动ST7789 2.0寸屏幕显示温湿度

[复制链接]
 楼主| xiaoqi976633690 发表于 2024-11-29 17:04 | 显示全部楼层 |阅读模式
本帖最后由 xiaoqi976633690 于 2024-11-29 17:04 编辑

#申请原创#
一、项目描述
1.项目介绍
项目基于AT-START-L021 V1.0  开发板驱动SPI 屏幕显示温湿度信息和倒计时器。
2.设计思路
SPI驱动采用硬件SPI和软件模拟SPI(可选)默认硬件SPI,I2C采用软件模拟时序。
3.硬件
2.0寸ST7789屏幕+AHT20温湿度传感器
二、软件代码说明
1.SPI初始化
注意事项
a.注意SPI的复用mux
  1. gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE5, GPIO_MUX_0);
  2.   gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE6, GPIO_MUX_0);
  3.   gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE7, GPIO_MUX_0);
b.注意SCK引脚内部下拉配置
  1.   gpio_initstructure.gpio_pull           = GPIO_PULL_DOWN;
c.注意SPI模式的配置关键点:  
1.spi_init_struct.mclk_freq_division = SPI_MCLK_DIV_2;//分频系数影响spi速率
2.spi_init_struct.first_bit_transmission = SPI_FIRST_BIT_MSB;//高位在前
3.  spi_init_struct.clock_polarity = SPI_CLOCK_POLARITY_LOW;//clk空闲为低  
  spi_init_struct.clock_phase = SPI_CLOCK_PHASE_1EDGE;//第一个边沿采样

  1. void SPI1_config(void)
  2. {
  3.         
  4.         spi_init_type spi_init_struct;
  5.         gpio_init_type gpio_initstructure;
  6.         
  7.   crm_periph_clock_enable(CRM_SPI1_PERIPH_CLOCK, TRUE);
  8.   crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
  9.   crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);

  10.   gpio_default_para_init(&gpio_initstructure);
  11.         
  12.         #ifdef SOFT_SPI
  13.         //SPI1_SCK
  14.   gpio_initstructure.gpio_out_type       = GPIO_OUTPUT_PUSH_PULL;
  15.   gpio_initstructure.gpio_pull           = GPIO_PULL_UP;
  16.   gpio_initstructure.gpio_mode           = GPIO_MODE_OUTPUT;
  17.   gpio_initstructure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  18.   gpio_initstructure.gpio_pins = GPIO_PINS_5;
  19.   gpio_init(GPIOA, &gpio_initstructure);
  20.         //SPI1_MOSI
  21.   gpio_initstructure.gpio_out_type       = GPIO_OUTPUT_PUSH_PULL;
  22.   gpio_initstructure.gpio_pull           = GPIO_PULL_UP;
  23.   gpio_initstructure.gpio_mode           = GPIO_MODE_OUTPUT;
  24.   gpio_initstructure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  25.   gpio_initstructure.gpio_pins = GPIO_PINS_7;
  26.   gpio_init(GPIOA, &gpio_initstructure);
  27.         #else
  28.         gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE5, GPIO_MUX_0);
  29.   gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE6, GPIO_MUX_0);
  30.   gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE7, GPIO_MUX_0);
  31.                 //SPI1_SCK
  32.   gpio_initstructure.gpio_out_type       = GPIO_OUTPUT_PUSH_PULL;
  33.   gpio_initstructure.gpio_pull           = GPIO_PULL_DOWN;
  34.   gpio_initstructure.gpio_mode           = GPIO_MODE_MUX;
  35.   gpio_initstructure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  36.   gpio_initstructure.gpio_pins = GPIO_PINS_5;
  37.   gpio_init(GPIOA, &gpio_initstructure);
  38.         //SPI1_MISO
  39.   gpio_initstructure.gpio_out_type       = GPIO_OUTPUT_PUSH_PULL;
  40.   gpio_initstructure.gpio_pull           = GPIO_PULL_UP;
  41.   gpio_initstructure.gpio_mode           = GPIO_MODE_MUX;
  42.   gpio_initstructure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  43.   gpio_initstructure.gpio_pins = GPIO_PINS_6;
  44.   gpio_init(GPIOA, &gpio_initstructure);
  45.         //SPI1_MOSI
  46.   gpio_initstructure.gpio_out_type       = GPIO_OUTPUT_PUSH_PULL;
  47.   gpio_initstructure.gpio_pull           = GPIO_PULL_UP;
  48.   gpio_initstructure.gpio_mode           = GPIO_MODE_MUX;
  49.   gpio_initstructure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  50.   gpio_initstructure.gpio_pins = GPIO_PINS_7;
  51.   gpio_init(GPIOA, &gpio_initstructure);         
  52. #endif
  53.                 //CS
  54.   gpio_initstructure.gpio_out_type       = GPIO_OUTPUT_PUSH_PULL;
  55.   gpio_initstructure.gpio_pull           = GPIO_PULL_UP;
  56.   gpio_initstructure.gpio_mode           = GPIO_MODE_OUTPUT;
  57.   gpio_initstructure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  58.   gpio_initstructure.gpio_pins = GPIO_PINS_0;
  59.   gpio_init(GPIOB, &gpio_initstructure);        
  60.                 //DC
  61.   gpio_initstructure.gpio_out_type       = GPIO_OUTPUT_PUSH_PULL;
  62.   gpio_initstructure.gpio_pull           = GPIO_PULL_UP;
  63.   gpio_initstructure.gpio_mode           = GPIO_MODE_OUTPUT;
  64.   gpio_initstructure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  65.   gpio_initstructure.gpio_pins = GPIO_PINS_1;
  66.   gpio_init(GPIOB, &gpio_initstructure);        
  67.                 //RESET
  68.   gpio_initstructure.gpio_out_type       = GPIO_OUTPUT_PUSH_PULL;
  69.   gpio_initstructure.gpio_pull           = GPIO_PULL_UP;
  70.   gpio_initstructure.gpio_mode           = GPIO_MODE_OUTPUT;
  71.   gpio_initstructure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  72.   gpio_initstructure.gpio_pins = GPIO_PINS_2;
  73.   gpio_init(GPIOB, &gpio_initstructure);        
  74.         //BLK
  75.   gpio_initstructure.gpio_out_type       = GPIO_OUTPUT_PUSH_PULL;
  76.   gpio_initstructure.gpio_pull           = GPIO_PULL_UP;
  77.   gpio_initstructure.gpio_mode           = GPIO_MODE_OUTPUT;
  78.   gpio_initstructure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  79.   gpio_initstructure.gpio_pins = GPIO_PINS_10;
  80.   gpio_init(GPIOB, &gpio_initstructure);        
  81.         
  82. //  LCD_SCLK_Clr();
  83. //        LCD_MOSI_Clr();

  84.         
  85.   spi_default_para_init(&spi_init_struct);
  86.   spi_init_struct.transmission_mode = SPI_TRANSMIT_FULL_DUPLEX;
  87.   spi_init_struct.master_slave_mode = SPI_MODE_MASTER;
  88.   spi_init_struct.mclk_freq_division = SPI_MCLK_DIV_2;
  89.   spi_init_struct.first_bit_transmission = SPI_FIRST_BIT_MSB;
  90.   spi_init_struct.frame_bit_num = SPI_FRAME_8BIT;
  91.   spi_init_struct.clock_polarity = SPI_CLOCK_POLARITY_LOW;
  92.   spi_init_struct.clock_phase = SPI_CLOCK_PHASE_1EDGE;
  93.   spi_init_struct.cs_mode_selection = SPI_CS_SOFTWARE_MODE;
  94.   spi_init(SPI1, &spi_init_struct);
  95.         
  96.   spi_enable(SPI1, TRUE);
  97.         LCD_DC_Set() ;
  98.         LCD_RES_Set();
  99.         LCD_CS_Set() ;
  100.         LCD_BLK_Set();
  101. }
2.LCD读写函数和初始化


  1. /******************************************************************************
  2.       函数说明:LCD串行数据写入函数
  3.       入口数据:dat  要写入的串行数据
  4.       返回值:  无
  5. ******************************************************************************/

  6. uint8_t spi_writebyte(uint8_t index,uint8_t TxData)
  7. {
  8.     uint8_t re;
  9.     while(spi_i2s_flag_get(SPI1, SPI_I2S_TDBE_FLAG) == RESET);
  10.     spi_i2s_data_transmit(SPI1, TxData);
  11.     while(spi_i2s_flag_get(SPI1, SPI_I2S_RDBF_FLAG) == RESET);
  12.     re = spi_i2s_data_receive(SPI1);
  13.     return re;
  14. }
  1. void LCD_Writ_Bus(u8 dat)
  2. {        

  3. #ifdef SOFT_SPI               
  4.                 u8 i;
  5.         LCD_CS_Clr();
  6.         for(i=0;i<8;i++)
  7.         {                          
  8.                 LCD_SCLK_Clr();
  9.                 if(dat&0x80)
  10.                 {
  11.                    LCD_MOSI_Set();
  12.                 }
  13.                 else
  14.                 {
  15.                    LCD_MOSI_Clr();
  16.                 }
  17.                 LCD_SCLK_Set();
  18.                 dat<<=1;
  19.         }        
  20.   LCD_CS_Set();        
  21. #else

  22.         LCD_CS_Clr();
  23.         spi_writebyte(0,dat);
  24.   LCD_CS_Set();        

  25. #endif
  26. }
至此SPI和屏幕驱动已基本完成。

3.软件i2c和AHT20驱动代码
a.软件I2C比较简单这里参考的是普中科技的代码,就不贴出来了。增加了个I2C 总线器件查找函数
  1. void scan_iic(void)
  2. {
  3.         u8 i=0,ack=1;
  4.         printf("iic scaner\n");
  5.         for(i=0;i<127;i=i+2)
  6.         {
  7.                 IIC_Start();
  8.                 IIC_Send_Byte(i);
  9.                 ack=IIC_Wait_Ack();
  10.                 if(ack==0) printf("0x%x  ",i>>1);
  11.                 IIC_Stop();
  12.         }
  13.         printf("\n");
  14. }
b.AHT20 温度读取函数
  1. void read_AHT20(void)
  2. {
  3.         uint8_t   i;
  4.         
  5.         for(i=0; i<6; i++)
  6.         {
  7.                 readByte[i]=0;
  8.         }
  9.         IIC_Start();//I2C启动

  10.         IIC_Send_Byte(0x71);//I2C写数据
  11.         ack_status = IIC_Wait_Ack();//收到的应答信息

  12.         readByte[0]= IIC_Read_Byte(1);//I2C读取数据

  13.         readByte[1]= IIC_Read_Byte(1);

  14.         readByte[2]= IIC_Read_Byte(1);

  15.         readByte[3]= IIC_Read_Byte(1);

  16.         readByte[4]= IIC_Read_Byte(1);

  17.         readByte[5]= IIC_Read_Byte(0);

  18.         IIC_Stop();//I2C停止函数
  19.         //判断读取到的第一个字节是不是0x08,0x08是该芯片读取流程中规定的,如果读取过程没有问题,就对读到的数据进行相应的处理
  20.         if( (readByte[0] & 0x68) == 0x08 )
  21.         {
  22.                 H1 = readByte[1];
  23.                 H1 = (H1<<8) | readByte[2];
  24.                 H1 = (H1<<8) | readByte[3];
  25.                 H1 = H1>>4;

  26.                 H1 = (H1*1000)/1024/1024;

  27.                 T1 = readByte[3];
  28.                 T1 = T1 & 0x0000000F;
  29.                 T1 = (T1<<8) | readByte[4];
  30.                 T1 = (T1<<8) | readByte[5];

  31.                 T1 = (T1*2000)/1024/1024 - 500;

  32.                 AHT20_OutData[0] = (H1>>8) & 0x000000FF;
  33.                 AHT20_OutData[1] = H1 & 0x000000FF;

  34.                 AHT20_OutData[2] = (T1>>8) & 0x000000FF;
  35.                 AHT20_OutData[3] = T1 & 0x000000FF;
  36.         }
  37.         else
  38.         {
  39.                
  40.                 AHT20_OutData[0] = 0xFF;
  41.                 AHT20_OutData[1] = 0xFF;

  42.                 AHT20_OutData[2] = 0xFF;
  43.                 AHT20_OutData[3] = 0xFF;
  44.                
  45.                 printf("读取失败!!!");

  46.         }
  47.         printf("\r\n");
  48.         //根据AHT20芯片中,温度和湿度的计算公式,得到最终的结果,通过串口显示
  49.         printf("温度:%d%d.%d",T1/100,(T1/10)%10,T1%10);
  50.         printf("湿度:%d%d.%d",H1/100,(H1/10)%10,H1%10);
  51.         
  52.         if(T1<=180)
  53.         {
  54.         LCD_ShowString(10,0,"T:",DARKBLUE,WHITE,32,0);
  55.   LCD_ShowFloatNum1(44,0,(float)T1/10,4,DARKBLUE,WHITE,32);
  56.         
  57.         LCD_ShowString(150+50,0,"H:",DARKBLUE,WHITE,32,0);        
  58.         LCD_ShowFloatNum1(184+50,0,(float)H1/10,4,DARKBLUE,WHITE,32);
  59.         }
  60.         else if(T1>180&&T1<270)
  61.         {
  62.                 LCD_ShowString(10,0,"T:",BRED,WHITE,32,0);
  63.                 LCD_ShowFloatNum1(44,0,(float)T1/10,4,BRED,WHITE,32);
  64.                 LCD_ShowString(150+50,0,"H:",BRED,WHITE,32,0);        
  65.           LCD_ShowFloatNum1(184+50,0,(float)H1/10,4,BRED,WHITE,32);
  66.                
  67.         }

  68.         printf("\r\n");
  69.         
  70. }
c.AHT20 子函数
  1. void  read_AHT20_once(void)
  2. {
  3.         delay_ms(10);

  4.         reset_AHT20();
  5.         delay_ms(10);

  6.         init_AHT20();
  7.         delay_ms(10);

  8.         startMeasure_AHT20();
  9.         delay_ms(80);

  10.         read_AHT20();
  11.         delay_ms(5);
  12.         
  13. }


  14. void  reset_AHT20(void)
  15. {

  16.         IIC_Start();

  17.         IIC_Send_Byte(0x70);
  18.         ack_status = IIC_Wait_Ack();
  19. //        if(ack_status) printf("1");
  20. //        else printf("1-n-");
  21.         IIC_Send_Byte(0xBA);
  22.         ack_status = IIC_Wait_Ack();
  23. //                if(ack_status) printf("2");
  24. //        else printf("2-n-");
  25.         IIC_Stop();

  26. }



  27. void  init_AHT20(void)
  28. {
  29.         IIC_Start();

  30.         IIC_Send_Byte(0x70);
  31.         ack_status = IIC_Wait_Ack();
  32. //        if(ack_status) printf("3");
  33. //        else printf("3-n-");        
  34.         IIC_Send_Byte(0xE1);
  35.         ack_status = IIC_Wait_Ack();
  36. //        if(ack_status) printf("4");
  37. //        else printf("4-n-");
  38.         IIC_Send_Byte(0x08);
  39.         ack_status = IIC_Wait_Ack();
  40. //        if(ack_status) printf("5");
  41. //        else printf("5-n-");
  42.         IIC_Send_Byte(0x00);
  43.         ack_status = IIC_Wait_Ack();
  44. //        if(ack_status) printf("6");
  45. //        else printf("6-n-");
  46.         IIC_Stop();
  47. }



  48. void  startMeasure_AHT20(void)
  49. {
  50.         //------------
  51.         IIC_Start();

  52.         IIC_Send_Byte(0x70);
  53.         ack_status = IIC_Wait_Ack();
  54. //        if(ack_status) printf("7");
  55. //        else printf("7-n-");
  56.         IIC_Send_Byte(0xAC);
  57.         ack_status = IIC_Wait_Ack();
  58. //        if(ack_status) printf("8");
  59. //        else printf("8-n-");
  60.         IIC_Send_Byte(0x33);
  61.         ack_status = IIC_Wait_Ack();
  62. //        if(ack_status) printf("9");
  63. //        else printf("9-n-");
  64.         IIC_Send_Byte(0x00);
  65.         ack_status = IIC_Wait_Ack();
  66. //        if(ack_status) printf("10");
  67. //        else printf("10-n-");
  68.         IIC_Stop();
  69. }

4.main函数
  1. int main(void)
  2. {
  3. //        float t=0.01;
  4.         u8 m=30,s=59;
  5.   system_clock_config();
  6.   at32_board_init();
  7.   uart_print_init(115200);
  8.         IIC_Init();
  9.         SPI1_config();
  10.         LCD_Init();
  11.        
  12.         LCD_Fill(0,0,LCD_H,LCD_W,WHITE);
  13. //        LCD_Show_MY_Char(10+65+65,45,10,my_color,WHITE,110,0);
  14.         scan_iic();
  15.        
  16.   while(1)
  17.   {               
  18.                
  19.                 s--;
  20.                 if(m<=0)
  21.                 {
  22.                         m=30;
  23.                 }
  24.                 if(s<=0)
  25.                 {
  26.                         s=60;
  27.                         m--;
  28.                 }

  29.                 LCD_Show_MY_Char(10,50,m/10%10,my_color,WHITE,110,0);
  30.                 LCD_Show_MY_Char(10+65,50,m%10,my_color,WHITE,110,0);
  31.                                        
  32.                 LCD_Fill(148,85,168,105,my_color);
  33.                 LCD_Fill(148,85+30,168,85+30+20,my_color);

  34.                 LCD_Show_MY_Char(10+65+60+45,50,s/10%10,my_color,WHITE,110,0);       
  35.                 LCD_Show_MY_Char(10+65+60+60+50,50,s%10,my_color,WHITE,110,0);
  36.                
  37.                 LCD_ShowPicture(55,170,202,50,gImage_AT);
  38.                 at32_led_toggle(LED4);
  39.         ///        printf("%d\n",Read1307(0x00));
  40.                 printf("UUID3=0x%x\n",UUID3);
  41.                 delay_ms(500);
  42.                 scan_iic();
  43.                 read_AHT20_once();
  44.                
  45.   }
  46. }

三、演示效果

0.png 2.jpg




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

本版积分规则

35

主题

204

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部