雅特力AT-START-F423开发板

2024-09-02 02:52
文章标签 start 开发板 特力 f423

本文主要是介绍雅特力AT-START-F423开发板,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

    • 1、开箱
    • 2、硬件设计
    • 3、点灯初试
    • 4、gpio输入和中断
    • 5、定时器基本定时
    • 6、定时器输出PWM
    • 7、串口使用
    • 8、ADC和DAC测试
    • 9、IIC驱动OLED测试
    • 10、SPI驱动测试
    • 11、总结

1、开箱

最近官方给寄了板子,顺便测评一下吧,首先是开箱环节
在这里插入图片描述
板子是调试器+开发板的布局,接口上用了typec接口好评
在这里插入图片描述
默认的是个流水灯的效果,来看个图
请添加图片描述
现在来了解下这个板子,资料的话参考这个官网的数据吧
https://www.arterytek.com/cn/product/AT32F423.jsp#Resource
这个芯片还是不错的,主打一个国产替代
在这里插入图片描述
这个是开发板的资料,直接下载这个压缩包就能拿到开发板的相关资料了
在这里插入图片描述
下面是keil的pack包,如果用keil开发的话就下载这个包然后安装就行了
在这里插入图片描述
让人比较惊喜的是这个,这是个开发工具,大概流程有点像stm32的cube的那一套了
在这里插入图片描述
如果用官方的工具来开发的话,大概流程是这样的:
· 1、先用下面的工具生成代码
在这里插入图片描述
· 2、使用at32ide写代码
在这里插入图片描述
编译和调试也都可以走at32ide来实现
在这里插入图片描述
当然也可以用keil来弄,只要在这个里面选一下使用mdk来生成就行了
在这里插入图片描述
之后就能打开了,编译也是正常的
在这里插入图片描述
调试器用默认的这个dsp就行
在这里插入图片描述
直接下载OK
在这里插入图片描述

2、硬件设计

看一下测评的这个开发板的参数吧,这个软件还挺好用的,打开就这样了
在这里插入图片描述
这个板子主频还不错,有150mhz,比st的一些f4的板子都要好了,时钟树如下
在这里插入图片描述
下面看下硬件吧,板子是核心板加调试器的布局,调试器也是一个at32的mcu,型号如下所示:
在这里插入图片描述
然后是核心板
在这里插入图片描述
5v-3.3v的ldo电路
在这里插入图片描述
再关注一下这里的按键和led
在这里插入图片描述

3、点灯初试

这里我们先用at32 ide来尝试吧,但是我感觉这个ide不太好用,有缺点,这个我们后面再说,先配置一下led
在这里插入图片描述
设置一下这三个led即可
在这里插入图片描述
可以在工具的代码预览看到代码
在这里插入图片描述
下面使用ide来打开,这里选择导入我们刚刚生成的工程
在这里插入图片描述
选择现有项目
在这里插入图片描述
之后选定刚刚的路径即可
在这里插入图片描述
打开工程就是这样了
在这里插入图片描述
点击左上角的锤子图标编译通过
在这里插入图片描述
下载的话要配置一下先
在这里插入图片描述
跟我一样就行
在这里插入图片描述
下载软件
在这里插入图片描述
如果要debug,就点击这个虫子就行,跑起来是这个样子
在这里插入图片描述
如果要添加自己的文件,尽量用这三个
在这里插入图片描述
包含路径就是属性里面的这个
在这里插入图片描述
当然也可以用keil来开发,生成代码的时候选一下mdk就行了
在这里插入图片描述
打开项目是这样的
在这里插入图片描述
下面开始点个灯,在固件库里面找到这个函数
在这里插入图片描述
然后它本身也有个延时函数,是这个wk_system.c里面的
在这里插入图片描述
代码大概就是这样的,就是循环亮三个灯了
在这里插入图片描述
但是我觉得他这个官方的延时函数不是很好用,就模仿正点原子重新弄了一套,基于嘀嗒定时器实现的,需要的自取,代码如下:
systick.c

/** systick.c**  Created on: 2024 Aug 5*      Author: lx*//***************************************************************************** @file     at32f423_board.c* @brief    set of firmware functions to manage leds and push-button.*           initialize delay function.***************************************************************************                       Copyright notice & Disclaimer** The software Board Support Package (BSP) that is made available to* download from Artery official website is the copyrighted work of Artery.* Artery authorizes customers to use, copy, and distribute the BSP* software and its related documentation for the purpose of design and* development in conjunction with Artery microcontrollers. Use of the* software is governed by this copyright notice and the following disclaimer.** THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,* GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,* TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR* STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,* INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.****************************************************************************/#include "systick.h"/** @addtogroup AT32F423_board* @{*//** @defgroup BOARD* @brief onboard periph driver* @{*//* delay macros */
#define STEP_DELAY_MS                    50/* delay variable */
static __IO uint32_t fac_us;
static __IO uint32_t fac_ms;/*** @brief  initialize delay function* @param  none* @retval none*/
void delay_init()
{/* configure systick */systick_clock_source_config(SYSTICK_CLOCK_SOURCE_AHBCLK_NODIV);fac_us = system_core_clock / (1000000U);fac_ms = fac_us * (1000U);
}/*** @brief  inserts a delay time.* @param  nus: specifies the delay time length, in microsecond.* @retval none*/
void delay_us(uint32_t nus)
{uint32_t temp = 0;SysTick->LOAD = (uint32_t)(nus * fac_us);SysTick->VAL = 0x00;SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk ;do{temp = SysTick->CTRL;}while((temp & 0x01) && !(temp & (1 << 16)));SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;SysTick->VAL = 0x00;
}/*** @brief  inserts a delay time.* @param  nms: specifies the delay time length, in milliseconds.* @retval none*/
void delay_ms(uint16_t nms)
{uint32_t temp = 0;while(nms){if(nms > STEP_DELAY_MS){SysTick->LOAD = (uint32_t)(STEP_DELAY_MS * fac_ms);nms -= STEP_DELAY_MS;}else{SysTick->LOAD = (uint32_t)(nms * fac_ms);nms = 0;}SysTick->VAL = 0x00;SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;do{temp = SysTick->CTRL;}while((temp & 0x01) && !(temp & (1 << 16)));SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;SysTick->VAL = 0x00;}
}/*** @brief  inserts a delay time.* @param  sec: specifies the delay time, in seconds.* @retval none*/
void delay_sec(uint16_t sec)
{uint16_t index;for(index = 0; index < sec; index++){delay_ms(500);delay_ms(500);}
}/*** @}*//*** @}*/

systick.h

/** systick.h**  Created on: 2024 Aug 5*      Author: lx*/#ifndef SYSTICK_H_
#define SYSTICK_H_#ifdef __cplusplus
extern "C" {
#endif#include "stdio.h"
#include "at32f423.h"/* delay function */
void delay_init(void);
void delay_us(uint32_t nus);
void delay_ms(uint16_t nms);
void delay_sec(uint16_t sec);/*** @}*//*** @}*//*** @}*/#ifdef __cplusplus
}
#endif#endif /* SYSTICK_H_ */

需要的话就添加如下:
在这里插入图片描述
使用逻辑分析仪测量,跟实际上的差了3ms
在这里插入图片描述

4、gpio输入和中断

上面的led算是gpio输出了,这个来看一下gpio输入吧,还是使用自家的图形化配置工具,选择pin,可以看到之前设置过的gpio
在这里插入图片描述
点开可以看到具体的io设置
在这里插入图片描述
这里我们的按键是PA0引脚,看电路默认是下拉的,按下后触发高电平
在这里插入图片描述
这里选一下下拉模式
在这里插入图片描述
保存代码后查看也能看到我们的修改
在这里插入图片描述
下面开始实现按键修改led状态,去库里面查找,应该就是这个函数了
在这里插入图片描述
简单实现一个轮询的方式,代码如下:
在这里插入图片描述
烧录后正常运行
在这里插入图片描述

下面实现一下中断触发吧,先还是在这里配置一下
在这里插入图片描述
上升沿
在这里插入图片描述
设置为下拉
在这里插入图片描述
最后开启一下中断
在这里插入图片描述
生成代码,然后打开,已经有中断的程序了
在这里插入图片描述
中断回调函数也自己生成了
在这里插入图片描述
把之前的逻辑放到这里,看下效果,也能实现按键触发中断
在这里插入图片描述
效果如下
在这里插入图片描述

5、定时器基本定时

下面实现一下定时器的基本定时功能,查看一下大概有这么多
在这里插入图片描述
数据手册中描述如下:
在这里插入图片描述
跟stm32比较相似,因此可以采用定时器6/7实现一个基本的定时器设置如下图(这样生成的时间是1ms一次的溢出)
在这里插入图片描述
其实我发现他这里还有个图,这个图就很直观了,对新手很友好
在这里插入图片描述

然后记得开中断
在这里插入图片描述
下面实现一下定时器点灯,下面的逻辑也是1s闪烁一次了
在这里插入图片描述
但是发现跑不起来,后面查了一下资料才发现原来有bug,要在这里加一行这个才行。
在这里插入图片描述
也用逻辑分析仪跑一下
在这里插入图片描述

6、定时器输出PWM

之前设置led的时候,发现这个led其实还绑定着pwm呢,例如下面的这个PD15,就绑定了TMR4的4通道,因此可以来测试一下这个定时器,这三个通道分别对应定时器4的的234通道,在下面设置一下
在这里插入图片描述
开启定时器
在这里插入图片描述
设置模式
在这里插入图片描述
使用下面的函数设置占空比
在这里插入图片描述
使用下面的函数设置占空比
在这里插入图片描述
逻辑分析仪测一下
在这里插入图片描述
在定时器的循环里面实现一下流水灯
在这里插入图片描述
效果如下:
在这里插入图片描述

7、串口使用

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
下面测试一下串口中断,在配置工具上开启这个中断
在这里插入图片描述
加入下面的回环测试程序

#define UART_BUFFER_LEN 20
uint8_t uart_buffer[UART_BUFFER_LEN] = {0};
uint8_t uart_rxindex = 0;
uint8_t uart_rxlen = 0;
uint8_t uart_txindex = 0;
uint8_t uart_txlen = 0;void starttx()
{uart_txlen += uart_rxlen;uart_rxlen = 0;usart_interrupt_enable(USART1, USART_TDBE_INT, TRUE);
}void USART1_IRQHandler(void)
{/* add user code begin USART1_IRQ 0 */if(usart_flag_get(USART1, USART_RDBF_FLAG) != RESET){usart_flag_clear(USART1, USART_RDBF_FLAG);uart_buffer[uart_rxindex++] = usart_data_receive(USART1);if(uart_rxindex == UART_BUFFER_LEN)uart_rxindex = 0;uart_rxlen++;}if(usart_flag_get(USART1, USART_IDLEF_FLAG) != RESET || uart_rxlen == UART_BUFFER_LEN/2){usart_flag_clear(USART1, USART_IDLEF_FLAG);starttx();}if(usart_flag_get(USART1, USART_TDBE_FLAG) != RESET){usart_flag_clear(USART1, USART_TDBE_FLAG);if(uart_txlen > 0){usart_data_transmit(USART1, uart_buffer[uart_txindex++]);if(uart_txindex == UART_BUFFER_LEN)uart_txindex = 0;uart_txlen--;}else{usart_interrupt_enable(USART1, USART_TDBE_INT, FALSE);}}/* add user code end USART1_IRQ 0 *//* add user code begin USART1_IRQ 1 *//* add user code end USART1_IRQ 1 */
}

接上串口,测试结果如下
在这里插入图片描述

8、ADC和DAC测试

下面开始测试adc,在图形化配置工具开启adc
在这里插入图片描述
这边的默认即可,这里我改到了12位,这样就是0-3.3v对应的0-4096的值
在这里插入图片描述
这里生成代码也要注意,开启这个才行
在这里插入图片描述
然后每次测试都加上这个
在这里插入图片描述
测试结果如下,可以看到adc正常工作
在这里插入图片描述
下面来测试使用dma的效果
在这里插入图片描述
对三个通道进行如下设置
在这里插入图片描述
定义一个数组来临时存储数据
在这里插入图片描述
根据生成代码的注释,这里是设置的地址
在这里插入图片描述
周期开启dma转换,开启中断和adc的转换
在这里插入图片描述
中断进行如下设置,就是在dma拿到数据后更新数据
在这里插入图片描述
下载测试结果如下:
在这里插入图片描述
下面测试dac,在配置工具中开启dac
在这里插入图片描述
这里直接设置默认就行
在这里插入图片描述
尝试设置一下电压
在这里插入图片描述
用万用表测量电压准确,实际上这个还有很多好玩的,可以生成噪声信号,正弦信号啥的,直接可以用,应该是sdk里面提供的,还是很舒服的。

9、IIC驱动OLED测试

开启iic,配置如下
在这里插入图片描述
这里面最坑的一点在这里,就是这个库里面没有常用的iic的函数
在这里插入图片描述
得加入这个库才行
在这里插入图片描述
这个库的函数如下,这才是我们要用的库
在这里插入图片描述

但是这个库又跟dma绑定了,所以为了防止编译错误,要开启这个才行
在这里插入图片描述
之后加入iic的驱动

#include "iic.h"#include "i2c_application.h"#define I2Cx_ADDRESS                     0x78#define I2Cx_PORT                        I2C1
#define I2Cx_CLK                         CRM_I2C1_PERIPH_CLOCK
#define I2Cx_DMA                         DMA1
#define I2Cx_DMA_CLK                     CRM_DMA1_PERIPH_CLOCK#define I2Cx_SCL_GPIO_CLK                CRM_GPIOB_PERIPH_CLOCK
#define I2Cx_SCL_GPIO_PIN                GPIO_PINS_6
#define I2Cx_SCL_GPIO_PinsSource         GPIO_PINS_SOURCE6
#define I2Cx_SCL_GPIO_PORT               GPIOB
#define I2Cx_SCL_GPIO_MUX                GPIO_MUX_4#define I2Cx_SDA_GPIO_CLK                CRM_GPIOB_PERIPH_CLOCK
#define I2Cx_SDA_GPIO_PIN                GPIO_PINS_7
#define I2Cx_SDA_GPIO_PinsSource         GPIO_PINS_SOURCE7
#define I2Cx_SDA_GPIO_PORT               GPIOB
#define I2Cx_SDA_GPIO_MUX                GPIO_MUX_4
#define I2Cx_CLKCTRL                   0x10F03C6A   //200Ki2c_handle_type hi2cx;/*** @brief  initializes peripherals used by the i2c.* @param  none* @retval none*/
void i2c_lowlevel_init(i2c_handle_type *hi2c)
{gpio_init_type gpio_init_structure;if (hi2c->i2cx == I2Cx_PORT) {/* i2c periph clock enable */crm_periph_clock_enable(I2Cx_CLK, TRUE);crm_periph_clock_enable(I2Cx_SCL_GPIO_CLK, TRUE);crm_periph_clock_enable(I2Cx_SDA_GPIO_CLK, TRUE);/* gpio configuration */gpio_pin_mux_config(I2Cx_SCL_GPIO_PORT, I2Cx_SCL_GPIO_PinsSource, I2Cx_SCL_GPIO_MUX);gpio_pin_mux_config(I2Cx_SDA_GPIO_PORT, I2Cx_SDA_GPIO_PinsSource, I2Cx_SDA_GPIO_MUX);/* configure i2c pins: scl */gpio_init_structure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;gpio_init_structure.gpio_mode           = GPIO_MODE_MUX;gpio_init_structure.gpio_out_type       = GPIO_OUTPUT_OPEN_DRAIN;gpio_init_structure.gpio_pull           = GPIO_PULL_UP;gpio_init_structure.gpio_pins           = I2Cx_SCL_GPIO_PIN;gpio_init(I2Cx_SCL_GPIO_PORT, &gpio_init_structure);/* configure i2c pins: sda */gpio_init_structure.gpio_pins           = I2Cx_SDA_GPIO_PIN;gpio_init(I2Cx_SDA_GPIO_PORT, &gpio_init_structure);/* config i2c */i2c_init(hi2c->i2cx, 0x0F, I2Cx_CLKCTRL);i2c_own_address1_set(hi2c->i2cx, I2C_ADDRESS_MODE_7BIT, I2Cx_ADDRESS);}
}void II2CGpioInit(void)
{
#if 0gpio_init_type gpio_init_struct;/* enable gpioc periph clock */crm_periph_clock_enable(CRM_GPIOC_PERIPH_CLOCK, TRUE);gpio_default_para_init(&gpio_init_struct);/* gpio output config */gpio_bits_write(GPIOC, IO_SCL_PIN | IO_SDA_PIN, TRUE);gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;gpio_init_struct.gpio_out_type = GPIO_OUTPUT_OPEN_DRAIN;gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;gpio_init_struct.gpio_pins = IO_SCL_PIN | IO_SDA_PIN;gpio_init_struct.gpio_pull = GPIO_PULL_UP;gpio_init(GPIOC, &gpio_init_struct);
#elsegpio_init_type gpio_init_structure;crm_periph_clock_enable(I2Cx_CLK, TRUE);crm_periph_clock_enable(I2Cx_SCL_GPIO_CLK, TRUE);crm_periph_clock_enable(I2Cx_SDA_GPIO_CLK, TRUE);/* gpio configuration */gpio_pin_mux_config(I2Cx_SCL_GPIO_PORT, I2Cx_SCL_GPIO_PinsSource, I2Cx_SCL_GPIO_MUX);gpio_pin_mux_config(I2Cx_SDA_GPIO_PORT, I2Cx_SDA_GPIO_PinsSource, I2Cx_SDA_GPIO_MUX);/* configure i2c pins: scl */gpio_init_structure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;gpio_init_structure.gpio_mode           = GPIO_MODE_MUX;gpio_init_structure.gpio_out_type       = GPIO_OUTPUT_OPEN_DRAIN;gpio_init_structure.gpio_pull           = GPIO_PULL_UP;gpio_init_structure.gpio_pins           = I2Cx_SCL_GPIO_PIN;gpio_init(I2Cx_SCL_GPIO_PORT, &gpio_init_structure);/* configure i2c pins: sda */gpio_init_structure.gpio_pins           = I2Cx_SDA_GPIO_PIN;gpio_init(I2Cx_SDA_GPIO_PORT, &gpio_init_structure);hi2cx.i2cx = I2Cx_PORT;/* i2c config */i2c_config(&hi2cx);
#endif
}
/****************************************************************************** @name       :void IIC_Start(void)* @date       :2018-09-13* @function   :start iic bus* @parameters :None* @retvalue   :None
******************************************************************************/
void IIC_Start(void)
{OLED_SCL_SET();OLED_SDA_SET();OLED_SDA_CLR();OLED_SCL_CLR();
}/****************************************************************************** @name       :void IIC_Stop(void)* @date       :2018-09-13* @function   :stop iic bus* @parameters :None* @retvalue   :None
******************************************************************************/
void IIC_Stop(void)
{OLED_SCL_SET();OLED_SDA_CLR();OLED_SDA_SET();
}/****************************************************************************** @name       :void IIC_Wait_Ack(void)* @date       :2018-09-13* @function   :wait iic ack* @parameters :None* @retvalue   :None
******************************************************************************/
void IIC_Wait_Ack(void)
{OLED_SCL_SET();OLED_SCL_CLR();
}/****************************************************************************** @name       :void Write_IIC_Byte(uint8_t IIC_Byte)* @date       :2018-09-13* @function   :Write a byte of content with iic bus* @parameters :IIC_Byte* @retvalue   :None
******************************************************************************/
void Write_IIC_Byte(uint8_t IIC_Byte)
{i2c_status_type i2c_status;
#if 0uint8_t i;uint8_t m, da;da = IIC_Byte;OLED_SCL_CLR();for (i = 0; i < 8; i++) {m = da;m = m & 0x80;if (m == 0x80) {OLED_SDA_SET();} else {OLED_SDA_CLR();}da = da << 1;OLED_SCL_SET();OLED_SCL_CLR();}#elseuint8_t buff[2] = {0};buff[0] = IIC_Byte;i2c_status = i2c_master_transmit(&hi2cx, I2Cx_ADDRESS, buff, 1, 1000);if (i2c_status != I2C_OK) {printf("erro send %d", i2c_status);}#endif
}/****************************************************************************** @name       :void Write_IIC_Command(uint8_t IIC_Command)* @date       :2018-09-13* @function   :Write a byte of command to oled screen* @parameters :IIC_Command:command to be written* @retvalue   :None
******************************************************************************/
void Write_IIC_Command(uint8_t IIC_Command)
{i2c_status_type i2c_status;
#if 0IIC_Start();Write_IIC_Byte(IIC_SLAVE_ADDR);            //Slave address,SA0=0IIC_Wait_Ack();Write_IIC_Byte(0x00);			//write commandIIC_Wait_Ack();Write_IIC_Byte(IIC_Command);IIC_Wait_Ack();IIC_Stop();
#elseuint8_t buff[2] = {0};buff[0] = 0x00;buff[1] = IIC_Command;i2c_status = i2c_master_transmit(&hi2cx, I2Cx_ADDRESS, buff, 2, 1000);if (i2c_status != I2C_OK) {printf("erro send %d", i2c_status);}#endif
}/****************************************************************************** @name       :void Write_IIC_Data(uint8_t IIC_Data)* @date       :2018-09-13* @function   :Write a byte of data to oled screen* @parameters :IIC_Data:data to be written* @retvalue   :None
******************************************************************************/
void Write_IIC_Data(uint8_t IIC_Data)
{i2c_status_type i2c_status;
#if 0IIC_Start();Write_IIC_Byte(IIC_SLAVE_ADDR);			//D/C#=0; R/W#=0IIC_Wait_Ack();Write_IIC_Byte(0x40);			//write dataIIC_Wait_Ack();Write_IIC_Byte(IIC_Data);IIC_Wait_Ack();IIC_Stop();
#elseuint8_t buff[2] = {0};buff[0] = 0x40;buff[1] = IIC_Data;i2c_status = i2c_master_transmit(&hi2cx, I2Cx_ADDRESS, buff, 2, 1000);if (i2c_status != I2C_OK) {printf("erro send %d", i2c_status);}#endif
}

iic.h

#ifndef _IIC_H_
#define _IIC_H_#include "at32f423.h"//本测试程序使用的是软件模拟IIC接口驱动
//IIC的数据引脚定义和时钟引脚定义都可以任意修改
//修改引脚定义后,需要对应修改oled.c中OLED_Init_GPIO函数里面引脚初始化//定义IIC从设备地址:OLED上设置的访问地址为0x78
#define IIC_SLAVE_ADDR 0x78//--------------IIC端口操作定义---------------------#define IO_SCL_PIN    GPIO_PINS_2
#define IO_SCL_GPIO_PORT    GPIOC
#define IO_SDA_PIN    GPIO_PINS_3
#define IO_SDA_GPIO_PORT    GPIOC#define	OLED_SDA_SET()  	gpio_bits_write(IO_SCL_GPIO_PORT, IO_SDA_PIN, TRUE)
#define	OLED_SDA_CLR()  	gpio_bits_write(IO_SCL_GPIO_PORT, IO_SDA_PIN, FALSE)#define	OLED_SCL_SET()  	gpio_bits_write(IO_SCL_GPIO_PORT, IO_SCL_PIN, TRUE)
#define	OLED_SCL_CLR()  	gpio_bits_write(IO_SCL_GPIO_PORT, IO_SCL_PIN, FALSE)//IIC操作函数
void II2CGpioInit(void);
void IIC_Start(void);
void IIC_Stop(void);
void IIC_Wait_Ack(void);
void Write_IIC_Byte(uint8_t IIC_Byte);
void Write_IIC_Command(uint8_t IIC_Command);
void Write_IIC_Data(uint8_t IIC_Data);#endif

使用下面代码测试
在这里插入图片描述
实现如下效果
在这里插入图片描述

10、SPI驱动测试

这里用一个spi的屏幕来测试spi,驱动是st7735
在这里插入图片描述
驱动代码如下

#include "lcd_init.h"
#include "systick.h"//#define delay_ms delay_1ms/******************************************************************* 函 数 名 称:LCD_GPIO_Init* 函 数 说 明:对LCD引脚初始化* 函 数 形 参:无* 函 数 返 回:无* 作       者:LC* 备       注:注意是使用软件SPI还是硬件SPI
******************************************************************/
void LCD_GPIO_Init(void)
{
#if 	USE_SOFTWARE/* 使能时钟 */
//    rcu_periph_clock_enable(RCU_LCD_CLK);
//    rcu_periph_clock_enable(RCU_LCD_MOS);
//    rcu_periph_clock_enable(RCU_LCD_CS);
//    rcu_periph_clock_enable(RCU_LCD_DC);
//    rcu_periph_clock_enable(RCU_LCD_RES);
//    rcu_periph_clock_enable(RCU_LCD_BLK);
//    
//    gpio_init(PORT_LCD_CLK, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_LCD_CLK);
//    gpio_bit_write(PORT_LCD_CLK, GPIO_LCD_CLK, SET);
//    
//    gpio_init(PORT_LCD_MOS, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_LCD_MOS);
//    gpio_bit_write(PORT_LCD_MOS, GPIO_LCD_MOS, SET);
//    
//    gpio_init(PORT_LCD_DC, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_LCD_DC);
//    gpio_bit_write(PORT_LCD_DC, GPIO_LCD_DC, SET);//    gpio_init(PORT_LCD_RES, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_LCD_RES);
//    gpio_bit_write(PORT_LCD_RES, GPIO_LCD_RES, SET);//    gpio_init(PORT_LCD_BLK, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_LCD_BLK);
//    gpio_bit_write(PORT_LCD_BLK, GPIO_LCD_BLK, SET);//    gpio_init(PORT_LCD_CS, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_LCD_CS);
//    gpio_bit_write(PORT_LCD_CS, GPIO_LCD_CS, SET);#elsespi_parameter_struct spi_init_struct;rcu_periph_clock_enable(RCU_LCD_CLK);rcu_periph_clock_enable(RCU_LCD_MOS);rcu_periph_clock_enable(RCU_LCD_CS);rcu_periph_clock_enable(RCU_LCD_DC);rcu_periph_clock_enable(RCU_LCD_RES);rcu_periph_clock_enable(RCU_LCD_BLK);rcu_periph_clock_enable(RCU_SPI_HARDWARE);  // 使能SPIrcu_periph_clock_enable(RCU_AF);gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_5 | GPIO_PIN_7);gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_6);gpio_init(PORT_LCD_DC, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_LCD_DC);gpio_bit_write(PORT_LCD_DC, GPIO_LCD_DC, SET);gpio_init(PORT_LCD_RES, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_LCD_RES);gpio_bit_write(PORT_LCD_RES, GPIO_LCD_RES, SET);gpio_init(PORT_LCD_BLK, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_LCD_BLK);gpio_bit_write(PORT_LCD_BLK, GPIO_LCD_BLK, SET);gpio_init(PORT_LCD_CS, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_LCD_CS);gpio_bit_write(PORT_LCD_CS, GPIO_LCD_CS, SET);/* 配置 SPI 参数 */spi_init_struct.trans_mode           = SPI_TRANSMODE_FULLDUPLEX;  // 传输模式全双工spi_init_struct.device_mode          = SPI_MASTER;   // 配置为主机spi_init_struct.frame_size           = SPI_FRAMESIZE_8BIT; // 8位数据spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE;spi_init_struct.nss                  = SPI_NSS_SOFT;  // 软件csspi_init_struct.prescale             = SPI_PSC_32;//2分频spi_init_struct.endian               = SPI_ENDIAN_MSB;spi_init(PORT_SPI, &spi_init_struct);/* 使能 SPI */spi_enable(PORT_SPI);
#endif
}/******************************************************************* 函 数 名 称:LCD_Writ_Bus* 函 数 说 明:LCD串行数据写入函数* 函 数 形 参:dat  要写入的串行数据* 函 数 返 回:无* 作       者:LC* 备       注:注意是使用软件SPI还是硬件SPI
******************************************************************/
void LCD_Writ_Bus(u8 dat)
{
#if USE_SOFTWAREu8 i;LCD_CS_Clr();for (i = 0; i < 8; i++) {LCD_SCLK_Clr();if (dat & 0x80) {LCD_MOSI_Set();} else {LCD_MOSI_Clr();}LCD_SCLK_Set();dat <<= 1;}LCD_CS_Set();
#elseLCD_CS_Clr();while (RESET == spi_i2s_flag_get(PORT_SPI, SPI_FLAG_TBE));spi_i2s_data_transmit(PORT_SPI, dat);while (RESET == spi_i2s_flag_get(PORT_SPI, SPI_FLAG_RBNE));spi_i2s_data_receive(PORT_SPI);LCD_CS_Set();
#endif
}/******************************************************************* 函 数 名 称:LCD_WR_DATA8* 函 数 说 明:LCD写入8位数据* 函 数 形 参:dat 写入的数据* 函 数 返 回:无* 作       者:LC* 备       注:无
******************************************************************/
void LCD_WR_DATA8(u8 dat)
{LCD_Writ_Bus(dat);
}/******************************************************************* 函 数 名 称:LCD_WR_DATA* 函 数 说 明:LCD写入16位数据* 函 数 形 参:dat 写入的数据* 函 数 返 回:无* 作       者:LC* 备       注:无
******************************************************************/
void LCD_WR_DATA(u16 dat)
{LCD_Writ_Bus(dat >> 8);LCD_Writ_Bus(dat);
}/******************************************************************* 函 数 名 称:LCD_WR_REG* 函 数 说 明:LCD写入命令* 函 数 形 参:dat 写入的命令* 函 数 返 回:无* 作       者:LC* 备       注:无
******************************************************************/
void LCD_WR_REG(u8 dat)
{LCD_DC_Clr();//写命令LCD_Writ_Bus(dat);LCD_DC_Set();//写数据
}/******************************************************************* 函 数 名 称:LCD_Address_Set* 函 数 说 明:设置起始和结束地址* 函 数 形 参:x1,x2 设置列的起始和结束地址y1,y2 设置行的起始和结束地址* 函 数 返 回:无* 作       者:LC* 备       注:无
******************************************************************/
void LCD_Address_Set(u16 x1, u16 y1, u16 x2, u16 y2)
{if (USE_HORIZONTAL == 0) {LCD_WR_REG(0x2a);//列地址设置LCD_WR_DATA(x1 + 2);LCD_WR_DATA(x2 + 2);LCD_WR_REG(0x2b);//行地址设置LCD_WR_DATA(y1 + 1);LCD_WR_DATA(y2 + 1);LCD_WR_REG(0x2c);//储存器写} else if (USE_HORIZONTAL == 1) {LCD_WR_REG(0x2a);//列地址设置LCD_WR_DATA(x1 + 2);LCD_WR_DATA(x2 + 2);LCD_WR_REG(0x2b);//行地址设置LCD_WR_DATA(y1 + 1);LCD_WR_DATA(y2 + 1);LCD_WR_REG(0x2c);//储存器写} else if (USE_HORIZONTAL == 2) {LCD_WR_REG(0x2a);//列地址设置LCD_WR_DATA(x1 + 1);LCD_WR_DATA(x2 + 1);LCD_WR_REG(0x2b);//行地址设置LCD_WR_DATA(y1 + 2);LCD_WR_DATA(y2 + 2);LCD_WR_REG(0x2c);//储存器写} else {LCD_WR_REG(0x2a);//列地址设置LCD_WR_DATA(x1 + 1);LCD_WR_DATA(x2 + 1);LCD_WR_REG(0x2b);//行地址设置LCD_WR_DATA(y1 + 2);LCD_WR_DATA(y2 + 2);LCD_WR_REG(0x2c);//储存器写}
}
/******************************************************************* 函 数 名 称:LCD_Init* 函 数 说 明:LCD初始化* 函 数 形 参:无* 函 数 返 回:无* 作       者:LC* 备       注:无
******************************************************************/
void LCD_Init(void)
{LCD_GPIO_Init();//初始化GPIOLCD_RES_Clr();//复位delay_ms(100);LCD_RES_Set();delay_ms(100);LCD_BLK_Set();//打开背光delay_ms(100);//************* Start Initial Sequence **********//LCD_WR_REG(0x11); //Sleep outdelay_ms(120);              //Delay 120ms//------------------------------------ST7735S Frame Rate-----------------------------------------//LCD_WR_REG(0xB1);LCD_WR_DATA8(0x05);LCD_WR_DATA8(0x3C);LCD_WR_DATA8(0x3C);LCD_WR_REG(0xB2);LCD_WR_DATA8(0x05);LCD_WR_DATA8(0x3C);LCD_WR_DATA8(0x3C);LCD_WR_REG(0xB3);LCD_WR_DATA8(0x05);LCD_WR_DATA8(0x3C);LCD_WR_DATA8(0x3C);LCD_WR_DATA8(0x05);LCD_WR_DATA8(0x3C);LCD_WR_DATA8(0x3C);//------------------------------------End ST7735S Frame Rate---------------------------------//LCD_WR_REG(0xB4); //Dot inversionLCD_WR_DATA8(0x03);//------------------------------------ST7735S Power Sequence---------------------------------//LCD_WR_REG(0xC0);LCD_WR_DATA8(0x28);LCD_WR_DATA8(0x08);LCD_WR_DATA8(0x04);LCD_WR_REG(0xC1);LCD_WR_DATA8(0XC0);LCD_WR_REG(0xC2);LCD_WR_DATA8(0x0D);LCD_WR_DATA8(0x00);LCD_WR_REG(0xC3);LCD_WR_DATA8(0x8D);LCD_WR_DATA8(0x2A);LCD_WR_REG(0xC4);LCD_WR_DATA8(0x8D);LCD_WR_DATA8(0xEE);//---------------------------------End ST7735S Power Sequence-------------------------------------//LCD_WR_REG(0xC5); //VCOMLCD_WR_DATA8(0x1A);LCD_WR_REG(0x36); //MX, MY, RGB modeif (USE_HORIZONTAL == 0) {LCD_WR_DATA8(0x00);} else if (USE_HORIZONTAL == 1) {LCD_WR_DATA8(0xC0);} else if (USE_HORIZONTAL == 2) {LCD_WR_DATA8(0x70);} else {LCD_WR_DATA8(0xA0);}//------------------------------------ST7735S Gamma Sequence---------------------------------//LCD_WR_REG(0xE0);LCD_WR_DATA8(0x04);LCD_WR_DATA8(0x22);LCD_WR_DATA8(0x07);LCD_WR_DATA8(0x0A);LCD_WR_DATA8(0x2E);LCD_WR_DATA8(0x30);LCD_WR_DATA8(0x25);LCD_WR_DATA8(0x2A);LCD_WR_DATA8(0x28);LCD_WR_DATA8(0x26);LCD_WR_DATA8(0x2E);LCD_WR_DATA8(0x3A);LCD_WR_DATA8(0x00);LCD_WR_DATA8(0x01);LCD_WR_DATA8(0x03);LCD_WR_DATA8(0x13);LCD_WR_REG(0xE1);LCD_WR_DATA8(0x04);LCD_WR_DATA8(0x16);LCD_WR_DATA8(0x06);LCD_WR_DATA8(0x0D);LCD_WR_DATA8(0x2D);LCD_WR_DATA8(0x26);LCD_WR_DATA8(0x23);LCD_WR_DATA8(0x27);LCD_WR_DATA8(0x27);LCD_WR_DATA8(0x25);LCD_WR_DATA8(0x2D);LCD_WR_DATA8(0x3B);LCD_WR_DATA8(0x00);LCD_WR_DATA8(0x01);LCD_WR_DATA8(0x04);LCD_WR_DATA8(0x13);//------------------------------------End ST7735S Gamma Sequence-----------------------------//LCD_WR_REG(0x3A); //65k modeLCD_WR_DATA8(0x05);LCD_WR_REG(0x29); //Display on
}

lcd_init.h

#ifndef __LCD_INIT_H
#define __LCD_INIT_H#include "at32f423.h"#ifndef u8
#define u8 uint8_t
#endif#ifndef u16
#define u16 uint16_t
#endif#ifndef u32
#define u32 uint32_t
#endif#define USE_SOFTWARE  1  //是否使用软件SPI 0使用硬件SPI  1使用软件SPI
#define USE_HORIZONTAL 1  //设置横屏或者竖屏显示 0或1为竖屏 2或3为横屏#if USE_HORIZONTAL==0||USE_HORIZONTAL==1
#define LCD_W 128
#define LCD_H 160#else
#define LCD_W 160
#define LCD_H 128
#endif//#define TCLK 		PBout(13)  	//PB13  SCLK--
//#define TDIN 		PBout(15)  	//PB15   MOSI--
//#define DOUT 		PBin(14)   	//PB14   MISO--
//#define TCS  		PGout(6)  	//PG6  CS2--
//#define PEN  		PGin(7)    //PG7  INT--//-----------------LCD端口移植----------------
//GND  - GND
//VCC  - 3.3V
//CLK  - PB13 SPI1_SCK
//MOS  - PB15 SPI1_MOSI
//RES  - PD0(可以接入复位)
//DC   - PC6
//BLK  - PC7- TIMER7_CH0
//MIS  - PB14 SPI1_MISO
//CS1  - PB12
//CS2  - PG6
//PEN  - PG7
//NC   - 不用接//#define RCU_LCD_CLK     RCU_GPIOA//SCK
#define PORT_LCD_CLK    GPIOA
#define GPIO_LCD_CLK    GPIO_PINS_6//#define RCU_LCD_MOS     RCU_GPIOA//MOSI
#define PORT_LCD_MOS    GPIOA
#define GPIO_LCD_MOS    GPIO_PINS_7//#define RCU_LCD_CS      RCU_GPIOE//NSS
#define PORT_LCD_CS     GPIOE
#define GPIO_LCD_CS     GPIO_PINS_10//#define RCU_LCD_DC      RCU_GPIOA //DC
#define PORT_LCD_DC     GPIOE
#define GPIO_LCD_DC     GPIO_PINS_11//#define RCU_LCD_RES     RCU_GPIOA//RES
#define PORT_LCD_RES    GPIOE
#define GPIO_LCD_RES    GPIO_PINS_12//#define RCU_LCD_BLK     RCU_GPIOA//BLK
#define PORT_LCD_BLK    GPIOE
#define GPIO_LCD_BLK    GPIO_PINS_13/******** 硬件SPI修改此次 ********/
//#define RCU_SPI_HARDWARE RCU_SPI0
//#define PORT_SPI         SPI0
//#define LINE_AF_SPI      GPIO_PINS_5//-----------------LCD端口定义----------------
#define LCD_SCLK_Clr() gpio_bits_write(PORT_LCD_CLK, GPIO_LCD_CLK, FALSE)//SCL=SCLK
#define LCD_SCLK_Set() gpio_bits_write(PORT_LCD_CLK, GPIO_LCD_CLK, TRUE)#define LCD_MOSI_Clr() gpio_bits_write(PORT_LCD_MOS, GPIO_LCD_MOS, FALSE)//SDA=MOSI
#define LCD_MOSI_Set() gpio_bits_write(PORT_LCD_MOS, GPIO_LCD_MOS, TRUE)#define LCD_RES_Clr()  gpio_bits_write(PORT_LCD_RES, GPIO_LCD_RES, FALSE)//RES
#define LCD_RES_Set()  gpio_bits_write(PORT_LCD_RES, GPIO_LCD_RES, TRUE)#define LCD_DC_Clr()   gpio_bits_write(PORT_LCD_DC, GPIO_LCD_DC, FALSE)//DC
#define LCD_DC_Set()   gpio_bits_write(PORT_LCD_DC, GPIO_LCD_DC, TRUE)#define LCD_CS_Clr()   gpio_bits_write(PORT_LCD_CS, GPIO_LCD_CS, FALSE)//CS
#define LCD_CS_Set()   gpio_bits_write(PORT_LCD_CS, GPIO_LCD_CS, TRUE)#define LCD_BLK_Clr()  gpio_bits_write(PORT_LCD_BLK, GPIO_LCD_BLK, FALSE)//BLK
#define LCD_BLK_Set()  gpio_bits_write(PORT_LCD_BLK, GPIO_LCD_BLK, TRUE)void LCD_GPIO_Init(void);//初始化GPIO
void LCD_Writ_Bus(u8 dat);//模拟SPI时序
void LCD_WR_DATA8(u8 dat);//写入一个字节
void LCD_WR_DATA(u16 dat);//写入两个字节
void LCD_WR_REG(u8 dat);//写入一个指令
void LCD_Address_Set(u16 x1, u16 y1, u16 x2, u16 y2); //设置坐标函数
void LCD_Init(void);//LCD初始化#endif

使用如下代码
在这里插入图片描述
测试效果如下

在这里插入图片描述

11、总结

首先这个板子性能很强,有stm32F4的水平了,这个没啥问题,然后生态也不错,这个是我觉得很好的地方,这决定了我在一些地方会用这个板子。
但是这个图形化配置工具还是有点bug,比如上次选了勾选全部库,第二次打开就不是了,然后就是iic的bug,希望后续能继续优化,然后希望这个图形化配置工具能融合到ide里面。

这篇关于雅特力AT-START-F423开发板的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1128799

相关文章

GNSS CTS GNSS Start and Location Flow of Android15

目录 1. 本文概述2.CTS 测试3.Gnss Flow3.1 Gnss Start Flow3.2 Gnss Location Output Flow 1. 本文概述 本来是为了做Android 14 Gnss CTS 的相关环境的搭建和测试,然后在测试中遇到了一些问题,去寻找CTS源码(/cts/tests/tests/location/src/android/locat

Oracle Start With关键字

Oracle Start With关键字 前言 旨在记录一些Oracle使用中遇到的各种各样的问题. 同时希望能帮到和我遇到同样问题的人. Start With (树查询) 问题描述: 在数据库中, 有一种比较常见得 设计模式, 层级结构 设计模式, 具体到 Oracle table中, 字段特点如下: ID, DSC, PID; 三个字段, 分别表示 当前标识的 ID(主键), DSC 当

笔记整理—内核!启动!—kernel部分(2)从汇编阶段到start_kernel

kernel起始与ENTRY(stext),和uboot一样,都是从汇编阶段开始的,因为对于kernel而言,还没进行栈的维护,所以无法使用c语言。_HEAD定义了后面代码属于段名为.head .text的段。         内核起始部分代码被解压代码调用,前面关于uboot的文章中有提到过(eg:zImage)。uboot启动是无条件的,只要代码的位置对,上电就工作,kern

开发板NFS挂载文件目录

文章目录 序NFS1. 安装 NFS 服务器和客户端在服务器上(NFS 服务器端)在客户端上(NFS 客户端) 2. 配置 NFS 服务器创建共享目录编辑 `/etc/exports` 文件启动 NFS 服务 3. 在客户端挂载 NFS 共享创建挂载点挂载 NFS 共享验证挂载 4. 设置开机自动挂载5. 解决权限问题 序 本节主要实现虚拟机(服务器)与开发板(客户端)通过N

Oracle start with connect BY 死循环

解决办法 检查start with前有没有where条件, 如果有的话,套一层select,再 Oracle start with connect BY

安卓开发板_联发科MTK开发评估套件串口调试

串口调试 如果正在进行lk(little kernel ) 或内核开发,USB 串口适配器( USB 转串口 TTL 适配器的简称)对于检查系统启动日志非常有用,特别是在没有图形桌面显示的情况下。 1.选购适配器 常用的许多 USB 转串口的适配器,按芯片来分,有以下几种: CH340PL2303CP2104FT232 一般来说,采用 CH340 芯片的适配器,性能比较稳定,价

MemSQL Start[c]UP 2.0 - Round 1A(构造)

题目链接:http://codeforces.com/problemset/problem/452/A 解题思路: 打个表暴力查找匹配。 完整代码: #include <algorithm>#include <iostream>#include <cstring>#include <complex>#include <cstdio>#include <strin

正点原子阿尔法ARM开发板-IMX6ULL(二)——介绍情况以及汇编

文章目录 一、裸机开发(21个)二、嵌入式Linux驱动例程三、汇编3.1 处理器内部数据传输指令3.2 存储器访问指令3.3 压栈和出栈指令3.4 跳转指令3.5 算术运算指令3.6 逻辑运算指令 一、裸机开发(21个) 二、嵌入式Linux驱动例程 三、汇编 我们在进行嵌入式 Linux 开发的时候是绝对要掌握基本的 ARM 汇编,因为 Cortex-A 芯片一

龙芯L2K0300开发板综合测试

CPU 查看cpu版本信息 cat /proc/cpuinfo 可以看到cpu是64位的LoongsonArch架构 stress压力测试结果 RAM 久久派板载512MB DDR4-2666内存,查看内存信息 cat /proc/meminfo 可以用memtester进行内存性能测试 memtester <size> <times> memtester测试结果

QT教程:start()和startTimer()的区别

start() - QTimer 类的成员函数         start() 是 QTimer 类的成员函数,用于启动一个基于 QTimer 对象的定时器。QTimer 是 Qt 中常用的定时器类,它会在设定的时间间隔后发出 timeout() 信号。 用法 QTimer timer;timer.start(1000); // 每隔 1000 毫秒触发一次 timeout() 信号