[AT32M412] 【AT-START-M412测评】+A/D数据采集与TFT屏显示

[复制链接]
 楼主| jinglixixi 发表于 2025-5-30 12:10 | 显示全部楼层 |阅读模式

A/D数模转换功能是常规开发板都具备的基本功能,对于AT-START-M412开发板来说自然也不例外。此外,利用A/D采集的多个检测通道还可实现多个目标的信号采集和感知,为能直观地以波形图的方式来观察,可利用开发板上的Arduino接口来快速连接一个TFT屏来实现。
以3通道的数据采集为例,其进行采集的配置函数为:
  1. static void adc_config(void)
  2. {
  3. adc_common_config_type adc_common_struct;
  4. adc_base_config_type adc_base_struct;
  5. crm_periph_clock_enable(CRM_ADC1_PERIPH_CLOCK, TRUE);
  6. nvic_irq_enable(ADC1_2_IRQn, 0, 0);
  7. adc_common_default_para_init(&adc_common_struct);
  8. adc_common_struct.combine_mode = ADC_INDEPENDENT_MODE;
  9. adc_common_struct.div = ADC_HCLK_DIV_6;
  10. adc_common_struct.common_dma_mode = ADC_COMMON_DMAMODE_DISABLE;
  11. adc_common_struct.common_dma_request_repeat_state = FALSE;
  12. adc_common_struct.sampling_interval = ADC_SAMPLING_INTERVAL_4CYCLES;
  13. adc_common_struct.tempervintrv_state = FALSE;
  14. adc_common_config(&adc_common_struct);
  15. adc_base_default_para_init(&adc_base_struct);
  16. adc_base_struct.sequence_mode = TRUE;
  17. adc_base_struct.repeat_mode = FALSE;
  18. adc_base_struct.data_align = ADC_RIGHT_ALIGNMENT;
  19. adc_base_struct.ordinary_channel_length = 2;
  20. adc_base_config(ADC1, &adc_base_struct);
  21. adc_resolution_set(ADC1, ADC_RESOLUTION_12B);
  22. adc_ordinary_channel_set(ADC1, ADC_CHANNEL_2, 1, ADC_SAMPLETIME_239_5);
  23. adc_ordinary_channel_set(ADC1, ADC_CHANNEL_4, 2, ADC_SAMPLETIME_239_5);
  24. adc_ordinary_conversion_trigger_set(ADC1, ADC_ORDINARY_TRIG_TMR1CH1, ADC_ORDINARY_TRIG_EDGE_NONE);
  25. adc_dma_mode_enable(ADC1, TRUE);
  26. adc_dma_request_repeat_enable(ADC1, TRUE);
  27. adc_occe_each_conversion_enable(ADC1, TRUE);
  28. adc_interrupt_enable(ADC1, ADC_OCCO_INT, TRUE);
  29. adc_interrupt_enable(ADC1, ADC_TCF_INT, TRUE);
  30. adc_convert_fail_auto_abort_enable(ADC1, TRUE);
  31. adc_enable(ADC1, TRUE);
  32. while(adc_flag_get(ADC1, ADC_RDY_FLAG) == RESET);
  33. adc_calibration_init(ADC1);
  34. while(adc_calibration_init_status_get(ADC1));
  35. adc_calibration_start(ADC1);
  36. while(adc_calibration_status_get(ADC1));
  37. }

经运行,其结果图1所示。
cf1c35a0e6290c9bf84008fe05447591
图1 数据采集结果

为进行数据显示和波形绘制,TFT屏使用的J3接口,见图2所示。
3d5c64457dba6b94045ceb5e06c73228
图2 所用接口

TFT屏的具体连接关系为:
CS----PA5
RST---PA6
DC---PA7
SD---PA15
SCK---PB7
LED---PA9

TFT屏的引脚配置函数为:
  1. void TFT_config()
  2. {
  3. gpio_init_type gpio_init_struct;
  4. crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
  5. gpio_default_para_init(&gpio_init_struct);
  6. gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  7. gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
  8. gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
  9. gpio_init_struct.gpio_pins = GPIO_PINS_5|GPIO_PINS_6|GPIO_PINS_7|GPIO_PINS_9|GPIO_PINS_15;
  10. gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  11. gpio_init(GPIOA, &gpio_init_struct);
  12. crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
  13. gpio_init_struct.gpio_pins = GPIO_PINS_7;
  14. gpio_init(GPIOB, &gpio_init_struct);
  15. }


显示屏的初始化函数为:
  1. void tft_Init(void)
  2. {
  3. // ili9220B
  4. LCD_REST_Low();
  5. delay_ms(20);
  6. LCD_REST_High();
  7. delay_ms(20);
  8. LCD_CS_Low();
  9. LCD_WR_REG(0xCB);
  10. LCD_WR_DATA8(0x39);
  11. LCD_WR_DATA8(0x2C);
  12. LCD_WR_DATA8(0x00);
  13. LCD_WR_DATA8(0x34);
  14. LCD_WR_DATA8(0x02);
  15. LCD_WR_REG(0xCF);
  16. LCD_WR_DATA8(0x00);
  17. LCD_WR_DATA8(0XC1);
  18. LCD_WR_DATA8(0X30);
  19. LCD_WR_REG(0xE8);
  20. LCD_WR_DATA8(0x85);
  21. LCD_WR_DATA8(0x00);
  22. LCD_WR_DATA8(0x78);
  23. LCD_WR_REG(0xEA);
  24. LCD_WR_DATA8(0x00);
  25. LCD_WR_DATA8(0x00);
  26. LCD_WR_REG(0xED);
  27. LCD_WR_DATA8(0x64);
  28. LCD_WR_DATA8(0x03);
  29. LCD_WR_DATA8(0X12);
  30. LCD_WR_DATA8(0X81);
  31. LCD_WR_REG(0xF7);
  32. LCD_WR_DATA8(0x20);
  33. LCD_WR_REG(0xC0); //Power control
  34. LCD_WR_DATA8(0x23); //VRH[5:0]
  35. LCD_WR_REG(0xC1); //Power control
  36. LCD_WR_DATA8(0x10); //SAP[2:0];BT[3:0]
  37. LCD_WR_REG(0xC5); //VCM control
  38. LCD_WR_DATA8(0x3e);
  39. LCD_WR_DATA8(0x28);
  40. LCD_WR_REG(0xC7); //VCM control2
  41. LCD_WR_DATA8(0x86); //--
  42. LCD_WR_REG(0x36); // Memory Access Control
  43. LCD_WR_DATA8(0x48);
  44. LCD_WR_REG(0x3A);
  45. LCD_WR_DATA8(0x55);
  46. LCD_WR_REG(0xB1);
  47. LCD_WR_DATA8(0x00);
  48. LCD_WR_DATA8(0x18);
  49. LCD_WR_REG(0xB6); // Display Function Control
  50. LCD_WR_DATA8(0x08);
  51. LCD_WR_DATA8(0x82);
  52. LCD_WR_DATA8(0x27);
  53. LCD_WR_REG(0xF2); // 3Gamma Function Disable
  54. LCD_WR_DATA8(0x00);
  55. LCD_WR_REG(0x26); //Gamma curve selected
  56. LCD_WR_DATA8(0x01);
  57. LCD_WR_REG(0xE0); //Set Gamma
  58. LCD_WR_DATA8(0x0F);
  59. LCD_WR_DATA8(0x31);
  60. LCD_WR_DATA8(0x2B);
  61. LCD_WR_DATA8(0x0C);
  62. LCD_WR_DATA8(0x0E);
  63. LCD_WR_DATA8(0x08);
  64. LCD_WR_DATA8(0x4E);
  65. LCD_WR_DATA8(0xF1);
  66. LCD_WR_DATA8(0x37);
  67. LCD_WR_DATA8(0x07);
  68. LCD_WR_DATA8(0x10);
  69. LCD_WR_DATA8(0x03);
  70. LCD_WR_DATA8(0x0E);
  71. LCD_WR_DATA8(0x09);
  72. LCD_WR_DATA8(0x00);
  73. LCD_WR_REG(0XE1); //Set Gamma
  74. LCD_WR_DATA8(0x00);
  75. LCD_WR_DATA8(0x0E);
  76. LCD_WR_DATA8(0x14);
  77. LCD_WR_DATA8(0x03);
  78. LCD_WR_DATA8(0x11);
  79. LCD_WR_DATA8(0x07);
  80. LCD_WR_DATA8(0x31);
  81. LCD_WR_DATA8(0xC1);
  82. LCD_WR_DATA8(0x48);
  83. LCD_WR_DATA8(0x08);
  84. LCD_WR_DATA8(0x0F);
  85. LCD_WR_DATA8(0x0C);
  86. LCD_WR_DATA8(0x31);
  87. LCD_WR_DATA8(0x36);
  88. LCD_WR_DATA8(0x0F);
  89. LCD_WR_REG(0x11); //Exit Sleep
  90. delay_ms(120);
  91. LCD_WR_REG(0x29); //Display on
  92. LCD_WR_REG(0x2c);
  93. LCD_LED_High();
  94. }


以软件方式模拟SPI进行字节数据方式的函数为:
  1. void LCD_Writ_Bus(unsigned char com)
  2. {


实现字符显示的函数为:
  1. void LCD_ShowChar(unsigned int x,unsigned int y,char num,char mode)
  2. {
  3. char temp;
  4. char pos,t;
  5. unsigned int x0=x;
  6. unsigned int colortemp=POINT_COLOR;
  7. if(x>LCD_W-16||y>LCD_H-16)return;
  8. num=num-' ';
  9. Address_set(x,y,x+8-1,y+16-1);
  10. if(!mode)
  11. {
  12. for(pos=0;pos<16;pos++)
  13. {
  14. temp=asc2_1608[(unsigned int)num*16+pos];
  15. for(t=0;t<8;t++)
  16. {
  17. if(temp&0x01)POINT_COLOR=colortemp;
  18. else POINT_COLOR=BACK_COLOR;
  19. LCD_WR_DATA(POINT_COLOR);
  20. temp>>=1;
  21. x++;
  22. }
  23. x=x0;
  24. y++;
  25. }
  26. }

实现数据显示的函数为:
  1. void LCD_ShowNum(unsigned int x,unsigned int y,unsigned int num,char len)
  2. {
  3. char t,temp;
  4. char enshow=0;
  5. num=(unsigned int)num;
  6. for(t=0;t<len;t++)
  7. {
  8. temp=(num/mypow(10,len-t-1))%10;
  9. if(enshow==0&&t<(len-1))
  10. {
  11. if(temp==0)
  12. {
  13. LCD_ShowChar(x+(8*t),y,' ',0);
  14. continue;
  15. }


实现字符串显示的函数为:
  1. void LCD_ShowString(unsigned int x,unsigned int y,const char *p)
  2. {
  3. while(*p!='\0')
  4. {
  5. if(x>LCD_W-16){x=0;y+=16;}
  6. if(y>LCD_H-16){y=x=0;}
  7. LCD_ShowChar(x,y,*p,0);
  8. x+=8;
  9. p++;
  10. }
  11. }

由于在进行多通道数据采集时会遇到引脚使用出现重叠的问题,为此这里仅使用PA2和PA4这2个引脚进行双通道的数据采集,这个引脚分别处于J5和J6上,见图3所示。
f6da592c412a25491f2f37721223153a b7a0f5be6009c44cb54c54b88625471d
图3  A/D采集所用接口

实现双通道数据采集及显示的主程序为:
  1. int main(void)
  2. {
  3. __IO uint32_t index = 0;
  4. nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
  5. system_clock_config();
  6. at32_board_init();
  7. at32_led_off(LED2);
  8. at32_led_off(LED3);
  9. at32_led_off(LED4);
  10. p_adc1_ordinary = adc1_ordinary_valuetab;
  11. uart_print_init(115200);
  12. gpio_config();
  13. TFT_config();
  14. tft_Init();
  15. LCD_Clear(RED);
  16. BACK_COLOR=RED;
  17. POINT_COLOR=YELLOW ;
  18. LCD_ShowString(20,10,"AT32M412 TEST!");
  19. LCD_ShowString(20,40,"adc1_channel_2 =");
  20. LCD_ShowString(20,60,"adc1_channel_4 =");
  21. adc_config();
  22. printf("use_polling_get_conversion_data \r\n");
  23. adc_ordinary_software_trigger_enable(ADC1, TRUE);
  24. while(1)
  25. {
  26. while(adc_flag_get(ADC1, ADC_OCCE_FLAG) == RESET);
  27. *(p_adc1_ordinary++) = adc_ordinary_conversion_data_get(ADC1);
  28. index++;
  29. if((adc1_overflow_flag != 0) || (adc1_conversion_fail_flag != 0))
  30. {
  31. adc_enable(ADC1, FALSE);
  32. at32_led_on(LED3);
  33. at32_led_on(LED4);
  34. printf("error occur\r\n");
  35. printf("adc1_overflow_flag = %d\r\n",adc1_overflow_flag);
  36. printf("adc1_conversion_fail_flag = %d\r\n",adc1_conversion_fail_flag);
  37. index = 0;
  38. adc_enable(ADC1, TRUE);
  39. }
  40. if(index%2 == 0)
  41. {
  42. LCD_ShowNum(160,40,adc1_ordinary_valuetab[0],4);
  43. LCD_ShowNum(160,60,adc1_ordinary_valuetab[1],4);
  44. delay_sec(1);
  45. p_adc1_ordinary = adc1_ordinary_valuetab;
  46. adc_ordinary_software_trigger_enable(ADC1, TRUE);
  47. }
  48. }
  49. }

经程序的编译和下载,其测试效果如图4所示。为测试通道2的响应效果,是将输入接到GND,说明检测值完全可得到零。
9f6b743b20193658c0aec0f7e1235c72
图4 测试效果


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

本版积分规则

517

主题

2932

帖子

39

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