- void adc_init(void)
- {
- gpio_init_t x;
- /* Initialize ADC pin */
- x.mode = GPIO_MODE_INPUT;
- x.pupd = GPIO_PUSH_UP;
- x.odrv = GPIO_OUT_DRIVE_NORMAL;
- x.flt = GPIO_FILTER_DISABLE;
- x.type = GPIO_TYPE_CMOS;
- x.func = GPIO_FUNC_0;
- ald_gpio_init(GPIO_CH_PORT, ADC_CH14_PIN, &x);
-
- /* clear adc_handle_t structure */
- memset(&h_adc, 0x0, sizeof(adc_handle_t));
- /* clear adc_nch_conf_t structure */
- memset(&nm_config, 0x0, sizeof(adc_nch_conf_t));
- /* Initialize adc */
- h_adc.perh = ADC0;
- h_adc.init.data_align = ADC_DATAALIGN_RIGHT;
- h_adc.init.scan_mode = DISABLE;
- h_adc.init.cont_mode = DISABLE;
- h_adc.init.nch_len = ADC_NCH_LEN_1;
- h_adc.init.disc_mode = ADC_ALL_DISABLE;
- h_adc.init.disc_nbr = ADC_DISC_NBR_1;
- h_adc.init.conv_res = ADC_CONV_RES_12;
- h_adc.init.clk_div = ADC_CKDIV_128;
- // h_adc.init.nche_sel = ADC_NCHESEL_MODE_ALL;
- h_adc.init.neg_ref = ADC_NEG_REF_VSS;
- h_adc.init.pos_ref = ADC_POS_REF_VDD;
- // h_adc.adc_reg_cplt_cbk = normal_convert_complete;
- // h_adc.adc_inj_cplt_cbk = insert_convert_complete;
- // h_adc.adc_out_of_win_cbk = out_window_complete;
- // h_adc.adc_error_cbk = error_complete;
- // h_adc.adc_ovr_cbk = ovr_complete;
- ald_adc_init(&h_adc);
- /* Initialize normal convert channel */
- nm_config.channel = ADC_CHANNEL_14;
- nm_config.rank = ADC_NCH_RANK_1;
- nm_config.samp_time = ADC_SAMPLETIME_4;
- ald_adc_normal_channel_config(&h_adc, &nm_config);
-
- return;
- }
在ADC初始化之后,就可以在主程序中直接使用了,直接将采集数据给myvolt即可,
代码如下:
- ald_adc_start_by_dma(&h_adc, &myvolt, 1, ADC_CHANNEL_0);
2)由于我设计的数据采集系统支持本地按钮切换操作,按钮才操作使用GPIO的INPUT功能即可,为了方便使用,使用中断方式,GPIO初始化代码如下:
- void key_init(void)
- {
- gpio_init_t x;
- exti_init_t exti;
- /* Initialize key exti pin as input */
- x.mode = GPIO_MODE_INPUT;
- x.odos = GPIO_PUSH_PULL;
- x.pupd = GPIO_PUSH_UP;
- x.odrv = GPIO_OUT_DRIVE_NORMAL;
- x.flt = GPIO_FILTER_DISABLE;
- x.type = GPIO_TYPE_CMOS;
- x.func = GPIO_FUNC_1;
- ald_gpio_init(GPIO_KEY_1_PORT, GPIO_KEY_1_PIN, &x);
- ald_gpio_init(GPIO_KEY_2_PORT, GPIO_KEY_2_PIN, &x);
- /* Initialize external interrupt */
- exti.filter = ENABLE;
- exti.cks = EXTI_FILTER_CLOCK_10K;
- exti.filter_time = 10;
- ald_gpio_exti_init(GPIO_KEY_1_PORT, GPIO_KEY_1_PIN, &exti);
- ald_gpio_exti_init(GPIO_KEY_2_PORT, GPIO_KEY_2_PIN, &exti);
- /* Clear interrupt flag */
- ald_gpio_exti_clear_flag_status(GPIO_KEY_1_PIN);
- ald_gpio_exti_clear_flag_status(GPIO_KEY_2_PIN);
- /* Configure interrupt */
- ald_gpio_exti_interrupt_config(GPIO_KEY_1_PIN, EXTI_TRIGGER_TRAILING_EDGE, ENABLE);
- ald_gpio_exti_interrupt_config(GPIO_KEY_2_PIN, EXTI_TRIGGER_TRAILING_EDGE, ENABLE);
- }
初始化完成之后,编写中断处理函数,由于分别使用A路和B路按钮,判断一下按钮即可,代码如下:
- void gpio_irq_handler(void)
- {
- /* Check and clear interrupt flag */
- if (ald_gpio_exti_get_flag_status(GPIO_KEY_1_PIN)) {
- ald_gpio_exti_clear_flag_status(GPIO_KEY_1_PIN);
- //ald_gpio_toggle_pin(LED1_PORT, LED1_PIN);
- ald_gpio_write_pin(LED2_PORT,LED2_PIN,1);
- //
- //这里可以加入防呆
- //
- ald_gpio_write_pin(LED1_PORT,LED1_PIN,0);
- FenLu=1;
- }
- if (ald_gpio_exti_get_flag_status(GPIO_KEY_2_PIN)) {
- ald_gpio_exti_clear_flag_status(GPIO_KEY_2_PIN);
- //ald_gpio_toggle_pin(LED2_PORT, LED2_PIN);
- ald_gpio_write_pin(LED2_PORT,LED2_PIN,0);
- //
- //这里可以加入防呆
- //
- ald_gpio_write_pin(LED1_PORT,LED1_PIN,1);
- FenLu=2;
- }
- return;
- }
3)由于我设计这套系统支持触摸屏切换A路和B路,触摸屏使用串口,所以串口的处理如下,先初始化触摸屏的串口UART1,代码如下:
- void uart1_init(void)
- {
- gpio_init_t x;
- /* Initialize tx pin */
- x.mode = GPIO_MODE_OUTPUT;
- x.odos = GPIO_PUSH_PULL;
- x.pupd = GPIO_PUSH_UP;
- x.odrv = GPIO_OUT_DRIVE_NORMAL;
- x.flt = GPIO_FILTER_DISABLE;
- x.type = GPIO_TYPE_TTL;
- x.func = GPIO_FUNC_3;
- ald_gpio_init(UART1_TX_PORT, UART1_TX_PIN, &x);
- /* Initialize rx pin */
- x.mode = GPIO_MODE_INPUT;
- x.odos = GPIO_PUSH_PULL;
- x.pupd = GPIO_PUSH_UP;
- x.odrv = GPIO_OUT_DRIVE_NORMAL;
- x.flt = GPIO_FILTER_DISABLE;
- x.type = GPIO_TYPE_TTL;
- x.func = GPIO_FUNC_3;
- ald_gpio_init(UART1_RX_PORT, UART1_RX_PIN, &x);
- /* clear uart_handle_t structure */
- memset(&h_uart1, 0x0, sizeof(h_uart1));
- /* Initialize tx_buf */
- memset(tx1_buf, 0x55, 32);
- /* Initialize uart */
- h_uart1.perh = UART1;
- h_uart1.init.baud = 115200;
- h_uart1.init.word_length = UART_WORD_LENGTH_8B;
- h_uart1.init.stop_bits = UART_STOP_BITS_1;
- h_uart1.init.parity = UART_PARITY_NONE;
- h_uart1.init.mode = UART_MODE_UART;
- h_uart1.init.fctl = UART_HW_FLOW_CTL_DISABLE;
- h_uart1.tx_cplt_cbk = uart1_send_complete;
- h_uart1.rx_cplt_cbk = uart1_recv_complete;
- h_uart1.error_cbk = uart1_error;
- ald_uart_init(&h_uart1);
- return;
- }
对于触摸屏的发送和接收直接在主函数里处理,代码如下:
- ald_uart_send_by_it(&h_uart1, tx1_buf, 10);
- ald_uart_recv_by_it(&h_uart1, rx1_buf, 8);
对于触摸屏的发送,无需我们处理,但是对于接收,我们必须处理,放在中断里处理,中断处理函数如下:
- void uart1_recv_complete(uart_handle_t *arg)
- {
-
- if(rx1_buf[0]==0x01&&rx1_buf[1]==0x06&&rx1_buf[6]==0x88&&rx1_buf[7]==0x99)
- {
- FenLu=rx1_buf[5];
- if(FenLu==1)
- {
- ald_gpio_write_pin(LED2_PORT,LED2_PIN,1);
- //
- //这里可以加入防呆
- //
- ald_gpio_write_pin(LED1_PORT,LED1_PIN,0);
- }
- if(FenLu==2)
- {
- ald_gpio_write_pin(LED2_PORT,LED2_PIN,0);
- //
- //这里可以加入防呆
- //
- ald_gpio_write_pin(LED1_PORT,LED1_PIN,1);
- }
- }
- return;
- }
4)在这套系统中,上位机电脑上的程序也是我自己编写,所以通讯速度、格式、协议我都完全掌控,所以采用串口,对串口UART2的初始化如下:
- <p>void uart2_init(void)
- {
- gpio_init_t x;</p><p> /* Initialize tx pin */
- x.mode = GPIO_MODE_OUTPUT;
- x.odos = GPIO_PUSH_PULL;
- x.pupd = GPIO_PUSH_UP;
- x.odrv = GPIO_OUT_DRIVE_NORMAL;
- x.flt = GPIO_FILTER_DISABLE;
- x.type = GPIO_TYPE_TTL;
- x.func = GPIO_FUNC_5;
- ald_gpio_init(UART2_TX_PORT, UART2_TX_PIN, &x);</p><p> /* Initialize rx pin */
- x.mode = GPIO_MODE_INPUT;
- x.odos = GPIO_PUSH_PULL;
- x.pupd = GPIO_PUSH_UP;
- x.odrv = GPIO_OUT_DRIVE_NORMAL;
- x.flt = GPIO_FILTER_DISABLE;
- x.type = GPIO_TYPE_TTL;
- x.func = GPIO_FUNC_5;
- ald_gpio_init(UART2_RX_PORT, UART2_RX_PIN, &x);</p><p> /* clear uart_handle_t structure */
- memset(&h_uart2, 0x0, sizeof(h_uart2));
- /* Initialize tx_buf */
- memset(tx2_buf, 0x56, 32);
- /* Initialize uart */
- h_uart2.perh = UART2;
- h_uart2.init.baud = 115200;
- h_uart2.init.word_length = UART_WORD_LENGTH_8B;
- h_uart2.init.stop_bits = UART_STOP_BITS_1;
- h_uart2.init.parity = UART_PARITY_NONE;
- h_uart2.init.mode = UART_MODE_UART;
- h_uart2.init.fctl = UART_HW_FLOW_CTL_DISABLE;
- h_uart2.tx_cplt_cbk = uart2_send_complete;
- h_uart2.rx_cplt_cbk = uart2_recv_complete;
- h_uart2.error_cbk = uart2_error;
- ald_uart_init(&h_uart2);
-
- return;
- }
- </p><p> </p>
对上位机的串口发送和接收也直接在主函数里处理即可,由于协议是我自己编写,发送、接收格式和触摸屏发送、接收格式一致,这样就方便许多,代码如下:
- ald_uart_send_by_it(&h_uart2, tx1_buf, 10);
- ald_uart_recv_by_it(&h_uart2, rx2_buf, 8);
对于上位机电脑的发送,无需我们处理,但是对于接收,我们必须处理,放在中断里处理,中断处理函数如下:
- void uart2_recv_complete(uart_handle_t *arg)
- {
-
- if(rx2_buf[0]==0x01&&rx2_buf[1]==0x06&&rx2_buf[6]==0x88&&rx2_buf[7]==0x99)
- {
- FenLu=rx2_buf[5];
- if(FenLu==1)
- {
- ald_gpio_write_pin(LED2_PORT,LED2_PIN,1);
- //
- //这里可以加入防呆
- //
- ald_gpio_write_pin(LED1_PORT,LED1_PIN,0);
- }
- if(FenLu==2)
- {
- ald_gpio_write_pin(LED2_PORT,LED2_PIN,0);
- //
- //这里可以加入防呆
- //
- ald_gpio_write_pin(LED1_PORT,LED1_PIN,1);
- }
- }
- return;
- }
至此,本套系统的全部代码都编写完成了,烧录到板子上进行试验,可以完美运行。
6.上位机电脑程序的编写,主要功能就是:
A.在上位机上显示A路和B路状态;
B.在上位机上显示采集的数据;
C.在上位机上进行A路和B路切换;
配合下位机可以完美运行:
五.演示视频:
1.使用按钮控制A/B路切换的视频地址;
https://www.bilibili.com/video/BV1Qt4y1C7nz
2.使用触摸屏控制A/B路切换的视频地址;
https://www.bilibili.com/video/BV1Fi4y1t7rk
3.使用上位机控制A/B路切换的视频地址;
https://www.bilibili.com/video/BV1Qp4y1Q7tE
4.设计的配电柜A/B路切换的综合演示视频地址:
https://www.bilibili.com/video/BV1rD4y1Q7Yd
六.源代码地址:
1.触摸屏源代码:按照以上步骤配置的触摸屏源代码只有一个文件:《触摸屏:RT-Thread创新大赛.HMI》,
2.东软载波RT-Thread源代码:按照以上步骤配置的源代码只有一个文件《main.c》,
其余涉及东软载波的代码直接直接从官网(http://www.essemi.com)下载即可;涉及RT-Thread的代码直接从RT-Thread官网(https://www.rt-thread.org)下载即可。
3.上位机使用VB写的,只有一个文件《上位机:RT-Thread创新大赛.frm》
七.总结:
1.东软载波板子功能很多,这个演示系统只用到:时钟、中断、ADC、GPIO、UART等几个简单的功能;
2. RT-Thread是一个功能强大的系统,这个演示系统只用到:RT-Thread内核、时钟、中断、延时等几个简单功能,RT-Thread很多高级功能和组件都没有用的,后续持续学习,争取将其完整版的高级功能和组件都尝试一把。
3.特别说明:RT-Thread的文档中心绝对值得所有程序员去学习的地方,是一个快速入手的最佳地方。
最后一个最重要的是这篇文案。