- 2025-02-24
-
回复了主题帖:
【AG32VH407开发板】测试mtimer定时器
秦天qintian0303 发表于 2025-2-24 08:20
MTimer属于高级定时器还是普通定时器
普通的吧,相当于滴答定时器
- 2025-02-23
-
发表了主题帖:
【AG32VH407开发板】模拟SPI方式驱动LCD12864
模拟SPI方式驱动LCD12864。
一、硬件部分
1.1、LCD接口
使用下面接口驱动
1.2、引脚定义
在example_board.ve中定义端口
二、程序部分
2.1、端口初始化部分
lcd端口定义和初始化部分
#define LCD_GPIO GPIO5
#define LCD_GPIO_MASK APB_MASK_GPIO5
#define LCD_GPIO_CLK GPIO5
#define LCD_GPIO_MOSI GPIO5
#define LCD_GPIO_MISO GPIO5
#define LCD_GPIO_CE GPIO5
#define LCD_GPIO_CS GPIO5
#define LCD_GPIO_CLK_BITS GPIO_BIT0
#define LCD_GPIO_MOSI_BITS GPIO_BIT1
#define LCD_GPIO_MISO_BITS GPIO_BIT2
#define LCD_GPIO_CE_BITS GPIO_BIT3
#define LCD_GPIO_CS_BITS GPIO_BIT4
void lcd_init_spi(void)
{
SYS_EnableAPBClock(LCD_GPIO_MASK);
GPIO_SetOutput(LCD_GPIO_CLK, LCD_GPIO_CLK_BITS);
GPIO_SetOutput(LCD_GPIO_MOSI, LCD_GPIO_MOSI_BITS);
GPIO_SetOutput(LCD_GPIO_MISO, LCD_GPIO_MISO_BITS);
GPIO_SetOutput(LCD_GPIO_CE, LCD_GPIO_CE_BITS);
GPIO_SetOutput(LCD_GPIO_CS, LCD_GPIO_CS_BITS);
}
2.2、lcd12864g.c
#include "board.h"
#include "lcd/jlx12864g_font.h"
#include "lcd/jlx12864g.h"
#include "timer/mtimer.h"
//[0]0 1 2 3 ... 127
//[1]0 1 2 3 ... 127
//[2]0 1 2 3 ... 127
//[3]0 1 2 3 ... 127
//[4]0 1 2 3 ... 127
//[5]0 1 2 3 ... 127
//[6]0 1 2 3 ... 127
//[7]0 1 2 3 ... 127
volatile static uint8_t lcdGram[128][8];
void lcd_init_spi(void)
{
SYS_EnableAPBClock(LCD_GPIO_MASK);
GPIO_SetOutput(LCD_GPIO_CLK, LCD_GPIO_CLK_BITS);
GPIO_SetOutput(LCD_GPIO_MOSI, LCD_GPIO_MOSI_BITS);
GPIO_SetOutput(LCD_GPIO_MISO, LCD_GPIO_MISO_BITS);
GPIO_SetOutput(LCD_GPIO_CE, LCD_GPIO_CE_BITS);
GPIO_SetOutput(LCD_GPIO_CS, LCD_GPIO_CS_BITS);
}
void lcd_jlx12864g_write_cmd(uint8_t cmd)
{
uint8_t i=0;
lcd_jlx12864g_cs_l();
lcd_jlx12864g_rs_l();
for(i=0;i<8;i++)
{
lcd_jlx12864g_clk_l();
if(cmd&0x80)
{
lcd_jlx12864g_sda_h();
}
else
{
lcd_jlx12864g_sda_l();
}
lcd_jlx12864g_clk_h();
cmd = cmd<<1;
}
}
void lcd_jlx12864g_write_dat(uint8_t dat)
{
uint8_t i=0;
lcd_jlx12864g_cs_l();
lcd_jlx12864g_rs_h();
for(i=0;i<8;i++)
{
lcd_jlx12864g_clk_l();
if(dat&0x80)
{
lcd_jlx12864g_sda_h();
}
else
{
lcd_jlx12864g_sda_l();
}
lcd_jlx12864g_clk_h();
dat = dat<<1;
}
}
/*
void lcd_jlx12864g_write_cmd(uint8_t cmd)
{
uint8_t i=0;
lcd_jlx12864g_cs_l();
lcd_jlx12864g_rs_l();
fc6_spi_writebyte(cmd);
}
void lcd_jlx12864g_write_dat(uint8_t dat)
{
uint8_t i=0;
lcd_jlx12864g_cs_l();
lcd_jlx12864g_rs_h();
fc6_spi_writebyte(dat);
}*/
void lcd_refreshGram(void)
{
uint8_t i,n;
for(i=0;i<8;i++)
{
lcd_jlx12864g_write_cmd (0xb0+i); //write page
lcd_jlx12864g_write_cmd (0x00);
lcd_jlx12864g_write_cmd (0x10);
for(n=0;n<128;n++)
lcd_jlx12864g_write_dat(lcdGram[n][i]);
}
}
void lcd_clear(void)
{
uint8_t i,n;
for(i=0;i<8;i++)
for(n=0;n<128;n++)
lcdGram[n][i]=0X00;
lcd_refreshGram();
}
void lcd_drawPoint(uint8_t x,uint8_t y,uint8_t t)
{
uint8_t pos,bx,temp=0;
if(x>127||y>63)return;
pos=7-y/8;
bx=y%8;
temp=1<<(7-bx);
if(t)lcdGram[x][pos]|=temp;
else lcdGram[x][pos]&=~temp;
}
//读点
//x:0~127
//y:0~63
uint8_t lcd_readPoint(uint8_t x,uint8_t y)
{
uint8_t pos,bx,temp=0x00;
//x = 127-x;
y = 63-y;
pos=y/8;
bx=y%8;
temp=1<<bx;
if(temp&lcdGram[x][pos]) return 1;
return 0;
}
//x1,y1,x2,y2 填充区域的对角坐标
//确保x1<=x2;y1<=y2 0<=x1<=127 0<=y1<=63
//dot:0,清空;1,填充
void lcd_fill(uint8_t x1,uint8_t y1,uint8_t x2,uint8_t y2,uint8_t dot)
{
uint8_t x,y;
for(x=x1;x<=x2;x++)
for(y=y1;y<=y2;y++)
lcd_drawPoint(x,y,dot);
// oled_refreshGram();//更新显示
}
//在指定位置显示一个字符,包括部分字符
//x:0~127
//y:0~63
//f_w:字宽
//f_h:字高
//mode:0,反白显示;1,正常显示
void lcd_showChar(uint8_t x,uint8_t y,uint8_t chr,uint8_t f_w,uint8_t f_h,uint8_t mode)
{
uint8_t temp,t,t1;
uint8_t y0=y;
uint8_t csize=(f_h/8+((f_h%8)?1:0))*f_w;
chr=chr-' ';
for(t=0;t<csize;t++)
{
if(f_w==6&&f_h==8)temp=asc2_0608[chr][t];
else if(f_w==6&&f_h==12)temp=asc2_0612[chr][t];
else if(f_w==12&&f_h==24)temp=asc2_1224[chr][t];
else return;
for(t1=0;t1<8;t1++)
{
if(temp&0x80)lcd_drawPoint(x,y,mode);
else lcd_drawPoint(x,y,!mode);
temp<<=1;
y++;
if((y-y0)==f_h)
{
y=y0;
x++;
break;
}
}
}
}
//m^n函数
uint32_t mypow(uint8_t m,uint8_t n)
{
uint32_t result=1;
while(n--)result*=m;
return result;
}
//显示2个数字
//x,y :起点坐标
//len :数字的位数
//f_w:字宽
//f_h:字高
//mode:模式 0,填充模式;1,叠加模式
//num:数值(0~4294967295);
void lcd_showNum(uint8_t x,uint8_t y,uint32_t num,uint8_t len,uint8_t f_w,uint8_t f_h)
{
uint8_t t,temp;
uint8_t enshow=0;
for(t=0;t<len;t++)
{
temp=(num/mypow(10,len-t-1))%10;
if(enshow==0&&t<(len-1))
{
if(temp==0)
{
lcd_showChar(x+(f_w)*t,y,' ',f_w,f_h,1);
continue;
}
else
enshow=1;
}
lcd_showChar(x+(f_w)*t,y,temp+'0',f_w,f_h,1);
}
}
//显示字符串
//x,y:起点坐标
//f_w:字宽
//f_h:字高
//*p:字符串起始地址
void lcd_showString(uint8_t x,uint8_t y,const uint8_t *p,uint8_t f_w,uint8_t f_h)
{
while((*p<='~')&&(*p>=' '))
{
if(x>(128-(f_w))){x=0;y+=f_h;}
if(y>(64-f_h)){y=x=0;lcd_clear();}
lcd_showChar(x,y,*p,f_w,f_h,1);
x+=f_w;
p++;
}
}
//显示图片
//x,y:起点坐标
//p_w:图片宽(单位像素)
//p_h:图片高(单位像素)
//*p:图片起始地址
void lcd_showPicture(uint8_t x,uint8_t y,const uint8_t *p,uint8_t p_w,uint8_t p_h)
{
uint8_t temp,i,col,row;
uint8_t y0=y;
uint8_t width=p_w;
if(x+p_w>128)width=128-p_w;//实际显示宽度
uint8_t high=p_h;
if(y+p_h>64)high=64-p_h;//实际显示高度
uint8_t exp_col_bytes=(p_h/8+((p_h%8)?1:0));//显示一列的字节数
uint8_t act_col_bytes=(high/8+((high%8)?1:0));//实际显示一列的字节数
for(row=0;row<width;row++)//列++
{
for(col=0;col<act_col_bytes;col++)//显示一列
{
temp = p[col+row*exp_col_bytes];
for(i=0;i<8;i++)
{
if(temp&0x80)lcd_drawPoint(x,y,1);
else lcd_drawPoint(x,y,0);
temp<<=1;
y++;
if((y-y0)==high)
{
y=y0;
x++;
break;
}
}
}
}
}
void init_lcd_jlx12864g(void)
{
// init_lcd_jlx12864g_pins();
lcd_init_spi();
lcd_jlx12864g_cs_l();
lcd_jlx12864g_rst_l();
mstimer_delay_ms(20);
lcd_jlx12864g_rst_h();
mstimer_delay_ms(20);
lcd_jlx12864g_write_cmd(0xe2);
lcd_jlx12864g_write_cmd(0x2c);
lcd_jlx12864g_write_cmd(0x2e);
lcd_jlx12864g_write_cmd(0x2f);
lcd_jlx12864g_write_cmd(0x23);
lcd_jlx12864g_write_cmd(0x81);
lcd_jlx12864g_write_cmd(0x28);
lcd_jlx12864g_write_cmd(0xa2);
lcd_jlx12864g_write_cmd(0xc0);
lcd_jlx12864g_write_cmd(0xa0);
lcd_jlx12864g_write_cmd(0x40);
lcd_jlx12864g_write_cmd(0xaf);
lcd_jlx12864g_cs_h();
lcd_clear();
//lcd_jlx12864g_bk_on();
}
2.3、lcd12864g.h
#ifndef __12864G_H
#define __12864G_H
#define LCD_GPIO GPIO5
#define LCD_GPIO_MASK APB_MASK_GPIO5
#define LCD_GPIO_CLK GPIO5
#define LCD_GPIO_MOSI GPIO5
#define LCD_GPIO_MISO GPIO5
#define LCD_GPIO_CE GPIO5
#define LCD_GPIO_CS GPIO5
#define LCD_GPIO_CLK_BITS GPIO_BIT0
#define LCD_GPIO_MOSI_BITS GPIO_BIT1
#define LCD_GPIO_MISO_BITS GPIO_BIT2
#define LCD_GPIO_CE_BITS GPIO_BIT3
#define LCD_GPIO_CS_BITS GPIO_BIT4
#define LCD_JLX12864G_CS_GPIO LCD_GPIO_CS
#define LCD_JLX12864G_CS_PIN LCD_GPIO_CS_BITS
#define LCD_JLX12864G_RST_GPIO LCD_GPIO_MISO
#define LCD_JLX12864G_RST_PIN LCD_GPIO_MISO_BITS
#define LCD_JLX12864G_RS_GPIO LCD_GPIO_CE
#define LCD_JLX12864G_RS_PIN LCD_GPIO_CE_BITS
#define LCD_JLX12864G_CLK_GPIO LCD_GPIO_CLK
#define LCD_JLX12864G_CLK_PIN LCD_GPIO_CLK_BITS
#define LCD_JLX12864G_MOSI_GPIO LCD_GPIO_MOSI
#define LCD_JLX12864G_MOSI_PIN LCD_GPIO_MOSI_BITS
//#define LCD_JLX12864G_BK_GPIO INIT_LCD_JLX12864G_PINS_ME_INT_GPIO
//#define LCD_JLX12864G_BK_PIN INIT_LCD_JLX12864G_PINS_ME_INT_GPIO_PIN
#define lcd_jlx12864g_cs_l() GPIO_SetLow(LCD_JLX12864G_CS_GPIO, LCD_JLX12864G_CS_PIN)
#define lcd_jlx12864g_cs_h() GPIO_SetHigh(LCD_JLX12864G_CS_GPIO, LCD_JLX12864G_CS_PIN)
#define lcd_jlx12864g_rs_l() GPIO_SetLow(LCD_JLX12864G_RS_GPIO, LCD_JLX12864G_RS_PIN)
#define lcd_jlx12864g_rs_h() GPIO_SetHigh(LCD_JLX12864G_RS_GPIO, LCD_JLX12864G_RS_PIN)
#define lcd_jlx12864g_rst_l() GPIO_SetLow(LCD_JLX12864G_RST_GPIO, LCD_JLX12864G_RST_PIN)
#define lcd_jlx12864g_rst_h() GPIO_SetHigh(LCD_JLX12864G_RST_GPIO, LCD_JLX12864G_RST_PIN)
#define lcd_jlx12864g_clk_l() GPIO_SetLow(LCD_JLX12864G_CLK_GPIO, LCD_JLX12864G_CLK_PIN)
#define lcd_jlx12864g_clk_h() GPIO_SetHigh(LCD_JLX12864G_CLK_GPIO, LCD_JLX12864G_CLK_PIN)
#define lcd_jlx12864g_sda_l() GPIO_SetLow(LCD_JLX12864G_MOSI_GPIO, LCD_JLX12864G_MOSI_PIN)
#define lcd_jlx12864g_sda_h() GPIO_SetHigh(LCD_JLX12864G_MOSI_GPIO, LCD_JLX12864G_MOSI_PIN)
#define lcd_jlx12864g_bk_off() GPIO_SetLow(LCD_JLX12864G_BK_GPIO, LCD_JLX12864G_BK_PIN)
#define lcd_jlx12864g_bk_on() GPIO_SetHigh(LCD_JLX12864G_BK_GPIO, LCD_JLX12864G_BK_PIN)
void fc6_spi_writebyte(uint8_t byte);
void lcd_refreshGram(void);
void lcd_clear(void) ;
void lcd_drawPoint(uint8_t x,uint8_t y,uint8_t t);
uint8_t lcd_readPoint(uint8_t x,uint8_t y);
void lcd_fill(uint8_t x1,uint8_t y1,uint8_t x2,uint8_t y2,uint8_t dot);
void lcd_showChar(uint8_t x,uint8_t y,uint8_t chr,uint8_t f_w,uint8_t f_h,uint8_t mode);
uint32_t mypow(uint8_t m,uint8_t n);
void lcd_showNum(uint8_t x,uint8_t y,uint32_t num,uint8_t len,uint8_t f_w,uint8_t f_h);
void lcd_showString(uint8_t x,uint8_t y,const uint8_t *p,uint8_t f_w,uint8_t f_h);
void lcd_showPicture(uint8_t x,uint8_t y,const uint8_t *p,uint8_t p_w,uint8_t p_h);
void init_lcd_jlx12864g(void);
#endif
2.4、example.c
#include "example.h"
#include "led/led.h"
#include "key/key.h"
#include "timer/mtimer.h"
#include "lcd/jlx12864g.h"
int main(void)
{
// This will init clock and uart on the board
board_init();
init_led();
init_key();
init_mtimer(1);
init_lcd_jlx12864g();
lcd_showString(0,0, (uint8_t*)"AG32_BOARD_TEST",6,12);
lcd_showString(0,13,(uint8_t*)"MCU:AG32VH407RCT",6,12);
lcd_showString(0,26,(uint8_t*)"JLX12864G-SPI",6,12);
lcd_showString(0,39,(uint8_t*)"2025/02/23",6,12);
lcd_refreshGram();
while(1)
{
mstimer_delay_ms(100);
led5_tog();
}
}
三、运行结果
下载程序运行后,显示屏显示
-
发表了主题帖:
【AG32VH407开发板】测试mtimer定时器
MTimer是RISC-V 中定义的一个 64 位系统定时器,相当于STM32中的systick定时器。
程序定时1ms,定时中断翻转IO_38引脚。
一、程序部分
1.1、mtimer.c
#include "board.h"
#include "key/key.h"
#include "led/led.h"
#include "timer/mtimer.h"
void mstimer_isr(void)
{
led3_tog();
INT_SetMtime(0);
}
void init_mtimer(int ms)
{
clint_isr[IRQ_M_TIMER] = mstimer_isr;
INT_SetMtime(0);
INT_SetMtimeCmp(SYS_GetSysClkFreq() / 1000 * ms);
INT_EnableIntTimer();
}
1.2、mstimer.h
#ifndef MTIMER_H
#define MTIMER_H
void init_mtimer(int ms);
#endif
1.3、example.c
#include "example.h"
#include "led/led.h"
#include "key/key.h"
#include "timer/mtimer.h"
int main(void)
{
board_init();
init_led();
init_key();
init_mtimer(1);
while(1)
{
}
}
三、运行结果
下载程序后,示波器测量LED3(IO_38)端口信号
-
发表了主题帖:
【AG32VH407开发板】外部中断测试
一、硬件部分
按键电路图部分,按键使用了IO35引脚
二、软件部分
2.1、配置IO35引脚
在example_board.ve中定义按键的引脚。
2.2、key.c
设置下降沿触发中断。
#include "board.h"
#include "key/key.h"
#include "led/led.h"
void user_key_isr(void)
{
if(GPIO_IsRawIntActive(USER_KEY_GPIO, USER_KEY_GPIO_BITS))
{
GPIO_ClearInt(USER_KEY_GPIO, USER_KEY_GPIO_BITS);
led2_tog();
printf("user key isr\r\n");
}
}
void init_key(void)
{
SYS_EnableAPBClock(USER_KEY_GPIO_MASK);
GPIO_SetInput(USER_KEY_GPIO, USER_KEY_GPIO_BITS);
GPIO_EnableInt(USER_KEY_GPIO, USER_KEY_GPIO_BITS);
GPIO_IntConfig(USER_KEY_GPIO, USER_KEY_GPIO_BITS, GPIO_INTMODE_FALLEDGE);
plic_isr[USER_KEY_GPIO_IRQ] = user_key_isr;
INT_EnableIRQ(USER_KEY_GPIO_IRQ, PLIC_MAX_PRIORITY);
}
void test_key(void)
{
if(GPIO_GetValue(USER_KEY_GPIO,USER_KEY_GPIO_BITS)==0)
{
printf("key\r\n");
}
}
2.3、key.h
#ifndef KEY_H
#define KEY_H
#define USER_KEY_GPIO GPIO4
#define USER_KEY_GPIO_MASK APB_MASK_GPIO4
#define USER_KEY_GPIO_BITS GPIO_BIT5
#define USER_KEY_GPIO_IRQ GPIO4_IRQn
void init_key(void);
void test_key(void);
#endif
2.4、example.c
#include "example.h"
#include "led/led.h"
#include "key/key.h"
int main(void)
{
board_init();
init_led();
init_key();
while(1)
{
}
}
三、运行结果
下载程序后,操作按键,串口输出
- 2025-02-21
-
回复了主题帖:
【AG32VH407开发板】搭建编译环境及测试GPIO输出
okhxyyo 发表于 2025-2-21 09:08
点灯亮起来啦~~~
嗯,按照例程修改引脚配置,可以运行亮灯。
-
发表了主题帖:
【AG32VH407开发板】搭建编译环境及测试GPIO输出
本帖最后由 TL-LED 于 2025-2-21 01:19 编辑
按照官方的《AG32开发环境搭建》文档来搭建编译环境。
一、下载软件
MCU部分软件下载地址:AGM32 软件链接: https://pan.baidu.com/s/17bp-zAnsYRuVMRTSSVHN5A 提取码: 12ej
电脑上之前安装过VSCODE和python软件,下面步骤直接在此软件上进行搭建,不再重新安装这两个软件。
SDK下载
下载最新版本的AgRV_pio-1.6.9
二、安装软件
2.1、安装步骤
按照官网的文档步骤:
2.1.1、下载安装软件和 SDK:
2.1.2、.安装 VSCODE(开发中的 IDE);
2.1.3、 安装 python;
2.1.4、 Vscode 中配置 SDK 环境;
2.1.5、编译 demo 样例程序;
2.2、安装SDK
选择安装的路径,直到安装完成。
2.3、配置vscode
搜索安装PlatformIO IDE插件
2.4、导入SDK目录
打开D:\agmWork\AgRV_pio\platforms\AgRV\examples\example下的文件
三、编译项目
编译项目,提示编译成功。
四、程序部分
手册上提到烧写程序有两部,一是VE配置(CPLD部分bin),一是AG32程序部分。那部分修改就烧写那部分,不分先后顺序。
新开发板第一次烧写必须先烧写VE部分,在烧写MCU部分。
烧录支持三种方式daplink、jlink和串口。下面使用官方的DAP仿真器下载。
4.1、配置仿真器
使用在线方式烧录,需要选择仿真器的类型
在文件platformio.ini文件中配置,这里选择cmsis-dap-openocd
4.2、配置platfromio.ini文件
board = agrv2k_103
logic_device = AGRV2KL64H
4.3、配置example_board.ve
根据开发板的端口配置此引脚信息
SYSCLK 200
#BUSCLK 100
HSECLK 8
UART0_UARTRXD PIN_43
UART0_UARTTXD PIN_42
GPIO4_1 PIN_39 # LED1
GPIO4_2 PIN_38 # LED2
GPIO4_3 PIN_37 # LED3
GPIO4_4 PIN_36 # LED4
4.4、main.c
int main(void)
{
// This will init clock and uart on the board
board_init();
// The default isr table is plic_isr. The default entries in the table are peripheral name based like CAN0_isr() or
// GPIO0_isr(), and can be re-assigned.
plic_isr[BUT_GPIO_IRQ] = Button_isr;
// Any interrupt priority needs to be greater than MIN_IRQ_PRIORITY to be effective
INT_SetIRQThreshold(MIN_IRQ_PRIORITY);
// Enable interrupt from BUT_GPIO
INT_EnableIRQ(BUT_GPIO_IRQ, PLIC_MAX_PRIORITY);
// TestMtimer(500);
// TestAnalog();
// TestCan();
// TestCrc();
// TestFcb();
// TestGpTimer();
// TestGpTimerPwm();
// TestI2c();
// TestRTC();
// TestSpi();
// TestSystem();
// TestTimer();
// TestWdog();
// TestUart();
// TestFlash();
TestGpio();
}
void TestGpio()
{
printf("Testing gpio\n");
int counter = 0;
while (1) {
printf("Testing gpio\r\n");
UTIL_IdleUs(100e3);
GPIO_Toggle(EXT_GPIO, EXT_GPIO_BITS);
}
}
4.5、烧写VE配置
烧写完成后,下面有提示成功。
4.6、烧写AG32程序
烧写完成后,下面有提示成功。
五、程序运行
5.1、串口输出
下载程序后,开发板运行,串口输出
5.2、指示灯闪烁
[localvideo]f54887356a9e1fe62ded6b046e60a532[/localvideo]
- 2025-02-14
-
回复了主题帖:
测评入围名单: 国产芯AGM 新品 AG32VH407(MCU+FPGA+64Mbit PSRAM)
个人信息无误,确认可以完成测评分享计划
-
回复了主题帖:
【兆易GD32H759I-EVAL】FreeRTOS系统移植
nkml 发表于 2025-2-14 14:32
我看过路径都没有选ARM的CMSIS文件, 可是文件里面又有, 您是单独添加的吗?
&n ...
这个没有单独添加
- 2025-02-12
-
回复了主题帖:
【FRDM-MCXN947】摄像头显示测试
oxlm_1 发表于 2025-2-11 19:35
我记得这板子要玩显示和摄像头,得改硬件,新版的硬件不需要改了?
摄像头需要跳线。
- 2025-02-09
-
发表了主题帖:
【FRDM-MCXN947】人脸识别检测环境搭建
本帖最后由 TL-LED 于 2025-2-9 21:26 编辑
N947基于两个运行频率高达150 MHz的高性能Arm Cortex-M33核,配备2 MB的Flash和可选的完整ECC RAM, 并集成了专有神经处理单元(NPU)。
一、导入项目
1.1、导入应用程序
1.2、搜索人脸识别例程
搜索:multiple face detection on mcxn947
1.3、从github上获取代码
1.4、导入的工程
1.5、编译工程
二、程序流程
2.1、数据流程图
2.2、程序逻辑结构框图
2.3、模型推理和后期处理
将所捕获图像的大小调整为160× 128,像素值被压缩至-1 - 1, 然后被输入到模型中进行推理。如图24所示, 有三种不同规模的预测输出。以左下角的第一个输出维度为例,输出维度16× 20× 18也可以表示为16× 20× 3× 6。16× 20表示原始图像被划分的区域数量,相当于320个方格。每个特征图对应三种尺寸的锚框(anchor box) ,所有网格共享这些锚框,每个锚框对应一个6维向量,即(tx、 ty、 th、 tw、 置信度、 类别) ,描述当前网格的推理结果。
三、结果
测试例程是基于LCD-PAR-S035显示屏模块显示的,手上没有这个模块,这里只熟悉例程的创建过程,后续有显示屏再测试具体的显示处理。
-
发表了主题帖:
【FRDM-MCXN947】摄像头显示测试
测试摄像头数据在屏幕上显示。
一、硬件部分
摄像头硬件部分电路图
二、程序部分
2.1、创建工程项目
导入官网的例程mpp_camera_view
2.2、修改显示屏参数
根据手上的屏幕修改参数
/*******************************************************************************
* Definitions
******************************************************************************/
/******** constant values ********/
#define HAL_DISPLAY_NAME "McuLcdSsd1963"
#define HAL_DISPLAY_DEV_McuLcdSsd1963_ROTATE ROTATE_0
#define HAL_DISPLAY_DEV_McuLcdSsd1963_BUFFER_COUNT 1
/******** configurable default values ********/
#define HAL_DISPLAY_DEV_McuLcdSsd1963_HEIGHT 480U
#define HAL_DISPLAY_DEV_McuLcdSsd1963_WIDTH 640U
#define HAL_DISPLAY_DEV_McuLcdSsd1963_LEFT 0
#define HAL_DISPLAY_DEV_McuLcdSsd1963_TOP 0
#define HAL_DISPLAY_DEV_McuLcdSsd1963_RIGHT (HAL_DISPLAY_DEV_McuLcdSsd1963_WIDTH - 1)
#define HAL_DISPLAY_DEV_McuLcdSsd1963_BOTTOM (HAL_DISPLAY_DEV_McuLcdSsd1963_HEIGHT - 1)
#define HAL_DISPLAY_DEV_McuLcdSsd1963_FORMAT MPP_PIXEL_RGB565
/* only RGB565 is supported */
#define HAL_DISPLAY_DEV_McuLcdSsd1963_BPP 2
/* default stripe height */
#define HAL_SMARTDMA_STRIPES 16
/* these macros represent the number of are used to define a small area of the screen in
* order to set the LCD background.
*/
#define HAL_DISPLAY_DEV_McuLcdSsd1963_NB_SUB_IMG_LINES 10
#define HAL_DISPLAY_DEV_McuLcdSsd1963_NB_SUB_IMG_COLUMNS 10
/******** macros for LCD controller ********/
/* pixel clock(LSHIFT clock) frequency(Hz) */
#define HAL_DISPLAY_DEV_McuLcdSsd1963_PCLK_FREQ 25000000U//30000000U
/* horizontal synchronization width(horizontal retrace) */
#define HAL_DISPLAY_DEV_McuLcdSsd1963_HSW 1U//48U
/* horizontal front porch */
#define HAL_DISPLAY_DEV_McuLcdSsd1963_HFP 116U//40U
/* horizontal back porch */
#define HAL_DISPLAY_DEV_McuLcdSsd1963_HBP 44U//0U
/* vertical synchronization width(vertical retrace) */
#define HAL_DISPLAY_DEV_McuLcdSsd1963_VSW 1U//3U
/* vertical front porch */
#define HAL_DISPLAY_DEV_McuLcdSsd1963_VFP 10U//13U
/* vertical back porch */
#define HAL_DISPLAY_DEV_McuLcdSsd1963_VBP 34U//18U
/* SSD1963 TFT interface timing polarity flag. */
#define HAL_DISPLAY_DEV_McuLcdSsd1963_POLARITY_FLAG 0U
三、运行结果
程序运行后,显示屏显示内容如下:
四、附件
程序源码:
- 2025-01-16
-
发表了主题帖:
【极海APM32M3514电机通用评估板】 驱动电机测试
驱动电机测试,开环方式测试。
测试电机是一个24V带减速器的无刷电机,由于电机其他参数不是很清楚,按照官网的手册进行测试。
根据官方文档《APM32M3514x8 MOTOR EVAL V1.0》对电机的参数进行设置
调试参数在parameter.h中设置
一、转速4000转测试
1.1、设置最高转速为4000转
1.2、 设置开环加速度和极对数
1.3、运行视频
[localvideo]086437c6c2ff4cfa9b99fb8c0980875b[/localvideo]
二、转速9000测试
2.1、设置转速参数
2.2、运行视频
[localvideo]d2785f196464282dde55df0302629e6a[/localvideo]
- 2025-01-08
-
发表了主题帖:
【FRDM-MCXN947】移植lwip及ping测试
测试开发板以太网,移植lwip并ping测试,参考SDK包里的例程进行移植。
一、硬件部分
开发板以太网接口部分电路图
二、配置接口
配置以太网对应的引脚
三、下载源码
下载lwip2.1.3版本
下载地址:http://download.savannah.nongnu.org/releases/lwip/
四、添加源码到工程
复制SDK工程中的部分源码和LWIP源码到工程目录下middleware文件中,并添加文件到工程。
五、程序部分
5.1、net_ping.c
#include "main.h"
/* IP address configuration. */
#ifndef configIP_ADDR0
#define configIP_ADDR0 192
#endif
#ifndef configIP_ADDR1
#define configIP_ADDR1 168
#endif
#ifndef configIP_ADDR2
#define configIP_ADDR2 1
#endif
#ifndef configIP_ADDR3
#define configIP_ADDR3 102
#endif
/* Netmask configuration. */
#ifndef configNET_MASK0
#define configNET_MASK0 255
#endif
#ifndef configNET_MASK1
#define configNET_MASK1 255
#endif
#ifndef configNET_MASK2
#define configNET_MASK2 255
#endif
#ifndef configNET_MASK3
#define configNET_MASK3 0
#endif
/* Gateway address configuration. */
#ifndef configGW_ADDR0
#define configGW_ADDR0 192
#endif
#ifndef configGW_ADDR1
#define configGW_ADDR1 168
#endif
#ifndef configGW_ADDR2
#define configGW_ADDR2 1
#endif
#ifndef configGW_ADDR3
#define configGW_ADDR3 1
#endif
/* Ethernet configuration. */
extern phy_lan8741_resource_t g_phy_resource;
#define EXAMPLE_ENET_BASE ENET0
#define EXAMPLE_PHY_ADDRESS BOARD_ENET0_PHY_ADDRESS
#define EXAMPLE_PHY_OPS &phylan8741_ops
#define EXAMPLE_PHY_RESOURCE &g_phy_resource
#define EXAMPLE_CLOCK_FREQ (50000000U)
/* Must be after include of app.h */
#ifndef configMAC_ADDR
#include "fsl_silicon_id.h"
#endif
#ifndef EXAMPLE_NETIF_INIT_FN
/*! [url=home.php?mod=space&uid=159083]@brief[/url] Network interface initialization function. */
#define EXAMPLE_NETIF_INIT_FN ethernetif0_init
#endif /* EXAMPLE_NETIF_INIT_FN */
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Variables
******************************************************************************/
phy_lan8741_resource_t g_phy_resource;
static phy_handle_t phyHandle;
/*******************************************************************************
* Code
******************************************************************************/
static void MDIO_Init(void)
{
(void)CLOCK_EnableClock(s_enetClock[ENET_GetInstance(EXAMPLE_ENET_BASE)]);
ENET_SetSMI(EXAMPLE_ENET_BASE, CLOCK_GetCoreSysClkFreq());
}
static status_t MDIO_Write(uint8_t phyAddr, uint8_t regAddr, uint16_t data)
{
return ENET_MDIOWrite(EXAMPLE_ENET_BASE, phyAddr, regAddr, data);
}
static status_t MDIO_Read(uint8_t phyAddr, uint8_t regAddr, uint16_t *pData)
{
return ENET_MDIORead(EXAMPLE_ENET_BASE, phyAddr, regAddr, pData);
}
void init_net(void)
{
struct netif netif;
ip4_addr_t netif_ipaddr, netif_netmask, netif_gw;
ethernetif_config_t enet_config =
{
.phyHandle = &phyHandle,
.phyAddr = EXAMPLE_PHY_ADDRESS,
.phyOps = EXAMPLE_PHY_OPS,
.phyResource = EXAMPLE_PHY_RESOURCE,
#ifdef configMAC_ADDR
.macAddress = configMAC_ADDR
#endif
};
CLOCK_AttachClk(MUX_A(CM_ENETRMIICLKSEL, 0));
CLOCK_EnableClock(kCLOCK_Enet);
SYSCON0->PRESETCTRL2 = SYSCON_PRESETCTRL2_ENET_RST_MASK;
SYSCON0->PRESETCTRL2 &= ~SYSCON_PRESETCTRL2_ENET_RST_MASK;
MDIO_Init();
g_phy_resource.read = MDIO_Read;
g_phy_resource.write = MDIO_Write;
time_init();
/* Set MAC address. */
#ifndef configMAC_ADDR
(void)SILICONID_ConvertToMacAddr(&enet_config.macAddress);
#endif
/* Get clock after hardware init. */
enet_config.srcClockHz = EXAMPLE_CLOCK_FREQ;
IP4_ADDR(&netif_ipaddr, configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3);
IP4_ADDR(&netif_netmask, configNET_MASK0, configNET_MASK1, configNET_MASK2, configNET_MASK3);
IP4_ADDR(&netif_gw, configGW_ADDR0, configGW_ADDR1, configGW_ADDR2, configGW_ADDR3);
lwip_init();
netif_add(&netif, &netif_ipaddr, &netif_netmask, &netif_gw, &enet_config, EXAMPLE_NETIF_INIT_FN, ethernet_input);
netif_set_default(&netif);
netif_set_up(&netif);
while (ethernetif_wait_linkup(&netif, 5000) != ERR_OK)
{
PRINTF("PHY Auto-negotiation failed. Please check the cable connection and link partner setting.\r\n");
}
ping_init(&netif_gw);
PRINTF("\r\n************************************************\r\n");
PRINTF(" PING example\r\n");
PRINTF("************************************************\r\n");
PRINTF(" IPv4 Address : %u.%u.%u.%u\r\n", ((u8_t *)&netif_ipaddr)[0], ((u8_t *)&netif_ipaddr)[1],
((u8_t *)&netif_ipaddr)[2], ((u8_t *)&netif_ipaddr)[3]);
PRINTF(" IPv4 Subnet mask : %u.%u.%u.%u\r\n", ((u8_t *)&netif_netmask)[0], ((u8_t *)&netif_netmask)[1],
((u8_t *)&netif_netmask)[2], ((u8_t *)&netif_netmask)[3]);
PRINTF(" IPv4 Gateway : %u.%u.%u.%u\r\n", ((u8_t *)&netif_gw)[0], ((u8_t *)&netif_gw)[1],
((u8_t *)&netif_gw)[2], ((u8_t *)&netif_gw)[3]);
PRINTF("************************************************\r\n");
while (1)
{
/* Poll the driver, get any outstanding frames */
ethernetif_input(&netif);
sys_check_timeouts(); /* Handle all system timeouts for all core protocols */
}
}
5.2、net_ping.h
#ifndef __NET_PING_H
#define __NET_PING_H
void init_net(void);
#endif
5.3、main.c
#include "main.h"
int main(void)
{
BOARD_InitDEBUG_UARTPins();
BOARD_PowerMode_OD();
BOARD_InitBootPins();
BOARD_InitBootClocks();
BOARD_InitDebugConsole();
SysTick_Init();
init_led();
init_key();
init_net();
while (1)
{
}
}
六、运行结果
6.1、下载程序后,复位开发板,连接网线,运行后串口输出
6.2、ping网络
七、附件
程序源码:
-
发表了主题帖:
【FRDM-MCXN947】CAN0收发测试
测试开发板上的CAN0通信,实现数据收发。
一、硬件部分
开发板上的CAN通信部分电路图
二、配置端口和时钟
2.1、CAN0端口配置
2.2、配置CAN0时钟
三、程序部分
3.1、can.c
#include "main.h"
#if (defined(USE_CANFD) && USE_CANFD)
/*
* DWORD_IN_MB DLC BYTES_IN_MB Maximum MBs
* 2 8 kFLEXCAN_8BperMB 64
* 4 10 kFLEXCAN_16BperMB 42
* 8 13 kFLEXCAN_32BperMB 25
* 16 15 kFLEXCAN_64BperMB 14
*
* Dword in each message buffer, Length of data in bytes, Payload size must align,
* and the Message Buffers are limited corresponding to each payload configuration:
*/
#define DLC (15)
#define BYTES_IN_MB kFLEXCAN_64BperMB
#else
#define DLC (8)
#endif
flexcan_handle_t flexcanHandle;
volatile bool txComplete = false;
volatile bool rxComplete = false;
volatile bool wakenUp = false;
flexcan_mb_transfer_t txXfer, rxXfer;
#if (defined(USE_CANFD) && USE_CANFD)
flexcan_fd_frame_t frame;
#else
flexcan_frame_t frame;
#endif
uint32_t txIdentifier;
uint32_t rxIdentifier;
static void FLEXCAN_PHY_Config(void)
{
#if (defined(USE_PHY_TJA1152) && USE_PHY_TJA1152)
/* Initialize TJA1152. */
/* STB=H, configuration CAN messages are expected from the local host via TXD pin. */
RGPIO_PortSet(EXAMPLE_STB_RGPIO, 1u << EXAMPLE_STB_RGPIO_PIN);
/* Classical CAN messages with standard identifier 0x555 must be transmitted
* by the local host controller until acknowledged by the TJA1152 for
* automatic bit rate detection. Do not set frame.brs = 1U to keep nominal
* bit rate in CANFD frame data phase. */
frame.id = FLEXCAN_ID_STD(0x555);
frame.format = (uint8_t)kFLEXCAN_FrameFormatStandard;
frame.type = (uint8_t)kFLEXCAN_FrameTypeData;
frame.length = 0U;
txXfer.mbIdx = (uint8_t)TX_MESSAGE_BUFFER_NUM;
#if (defined(USE_CANFD) && USE_CANFD)
txXfer.framefd = &frame;
(void)FLEXCAN_TransferFDSendNonBlocking(EXAMPLE_CAN, &flexcanHandle, &txXfer);
#else
txXfer.frame = &frame;
(void)FLEXCAN_TransferSendNonBlocking(EXAMPLE_CAN, &flexcanHandle, &txXfer);
#endif
while (!txComplete)
{
};
txComplete = false;
/* Configuration of spoofing protection. */
/* Add 0x321 and 0x123 to Transmission Whitelist. */
frame.id = FLEXCAN_ID_EXT(0x18DA00F1);
frame.format = (uint8_t)kFLEXCAN_FrameFormatExtend;
frame.type = (uint8_t)kFLEXCAN_FrameTypeData;
frame.length = 6U;
#if (defined(USE_CANFD) && USE_CANFD)
frame.dataWord[0] = CAN_WORD_DATA_BYTE_0(0x10) | CAN_WORD_DATA_BYTE_1(0x00) | CAN_WORD_DATA_BYTE_2(0x33) |
CAN_WORD_DATA_BYTE_3(0x21);
frame.dataWord[1] = CAN_WORD_DATA_BYTE_4(0x11) | CAN_WORD_DATA_BYTE_5(0x23);
(void)FLEXCAN_TransferFDSendNonBlocking(EXAMPLE_CAN, &flexcanHandle, &txXfer);
#else
frame.dataWord0 = CAN_WORD0_DATA_BYTE_0(0x10) | CAN_WORD0_DATA_BYTE_1(0x00) | CAN_WORD0_DATA_BYTE_2(0x33) |
CAN_WORD0_DATA_BYTE_3(0x21);
frame.dataWord1 = CAN_WORD1_DATA_BYTE_4(0x11) | CAN_WORD1_DATA_BYTE_5(0x23);
(void)FLEXCAN_TransferSendNonBlocking(EXAMPLE_CAN, &flexcanHandle, &txXfer);
#endif
while (!txComplete)
{
};
txComplete = false;
/* Configuration of command message ID. */
/* Reconfiguration is only accepted locally. Keep CONFIG_ID as default value 0x18DA00F1. */
frame.length = 5U;
#if (defined(USE_CANFD) && USE_CANFD)
frame.dataWord[0] = CAN_WORD_DATA_BYTE_0(0x60) | CAN_WORD_DATA_BYTE_1(0x98) | CAN_WORD_DATA_BYTE_2(0xDA) |
CAN_WORD_DATA_BYTE_3(0x00);
frame.dataWord[1] = CAN_WORD_DATA_BYTE_4(0xF1);
(void)FLEXCAN_TransferFDSendNonBlocking(EXAMPLE_CAN, &flexcanHandle, &txXfer);
#else
frame.dataWord0 = CAN_WORD0_DATA_BYTE_0(0x60) | CAN_WORD0_DATA_BYTE_1(0x98) | CAN_WORD0_DATA_BYTE_2(0xDA) |
CAN_WORD0_DATA_BYTE_3(0x00);
frame.dataWord1 = CAN_WORD1_DATA_BYTE_4(0xF1);
(void)FLEXCAN_TransferSendNonBlocking(EXAMPLE_CAN, &flexcanHandle, &txXfer);
#endif
while (!txComplete)
{
};
txComplete = false;
/* Leaving configuration mode. */
/* Configuration into volatile memory only. */
frame.length = 8U;
#if (defined(USE_CANFD) && USE_CANFD)
frame.dataWord[0] = CAN_WORD_DATA_BYTE_0(0x71) | CAN_WORD_DATA_BYTE_1(0x02) | CAN_WORD_DATA_BYTE_2(0x03) |
CAN_WORD_DATA_BYTE_3(0x04);
frame.dataWord[1] = CAN_WORD_DATA_BYTE_4(0x05) | CAN_WORD_DATA_BYTE_5(0x06) | CAN_WORD_DATA_BYTE_6(0x07) |
CAN_WORD_DATA_BYTE_7(0x08);
(void)FLEXCAN_TransferFDSendNonBlocking(EXAMPLE_CAN, &flexcanHandle, &txXfer);
#else
frame.dataWord0 = CAN_WORD0_DATA_BYTE_0(0x71) | CAN_WORD0_DATA_BYTE_1(0x02) | CAN_WORD0_DATA_BYTE_2(0x03) |
CAN_WORD0_DATA_BYTE_3(0x04);
frame.dataWord1 = CAN_WORD1_DATA_BYTE_4(0x05) | CAN_WORD1_DATA_BYTE_5(0x06) | CAN_WORD1_DATA_BYTE_6(0x07) |
CAN_WORD1_DATA_BYTE_7(0x08);
(void)FLEXCAN_TransferSendNonBlocking(EXAMPLE_CAN, &flexcanHandle, &txXfer);
#endif
while (!txComplete)
{
};
txComplete = false;
LOG_INFO("Initialize TJA1152 successfully!\r\n\r\n");
/* STB=L, TJA1152 switch from secure standby mode to normal mode. */
RGPIO_PortClear(EXAMPLE_STB_RGPIO, 1u << EXAMPLE_STB_RGPIO_PIN);
/* Initialize TJA1152 end. */
#endif
}
/*!
* [url=home.php?mod=space&uid=159083]@brief[/url] FlexCAN Call Back function
*/
static FLEXCAN_CALLBACK(flexcan_callback)
{
switch (status)
{
case kStatus_FLEXCAN_RxIdle:
if (RX_MESSAGE_BUFFER_NUM == result)
{
rxComplete = true;
}
break;
case kStatus_FLEXCAN_TxIdle:
if (TX_MESSAGE_BUFFER_NUM == result)
{
txComplete = true;
}
break;
case kStatus_FLEXCAN_WakeUp:
wakenUp = true;
break;
default:
break;
}
}
uint8_t can_rx_hdl(uint8_t *rxbuf)
{
uint8_t can_tx_buf[8];
/* Start receive data through Rx Message Buffer. */
rxXfer.mbIdx = (uint8_t)RX_MESSAGE_BUFFER_NUM;
#if (defined(USE_CANFD) && USE_CANFD)
rxXfer.framefd = &frame;
(void)FLEXCAN_TransferFDReceiveNonBlocking(EXAMPLE_CAN, &flexcanHandle, &rxXfer);
#else
rxXfer.frame = &frame;
(void)FLEXCAN_TransferReceiveNonBlocking(EXAMPLE_CAN, &flexcanHandle, &rxXfer);
#endif
if(rxComplete==true)
{
rxComplete=false;
LOG_INFO(" Rx MB ID: 0x%3x, Rx MB data: %02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x \r\n", frame.id >> CAN_ID_STD_SHIFT,frame.dataByte0,frame.dataByte1,frame.dataByte2,frame.dataByte3,
frame.dataByte4,frame.dataByte5,frame.dataByte6,frame.dataByte7);
rxbuf[0] = frame.dataByte0;
rxbuf[1] = frame.dataByte1;
rxbuf[2] = frame.dataByte2;
rxbuf[3] = frame.dataByte3;
rxbuf[4] = frame.dataByte4;
rxbuf[5] = frame.dataByte5;
rxbuf[6] = frame.dataByte6;
rxbuf[7] = frame.dataByte7;
return 1;
}
return 0;
}
void can_std_tx(uint32_t id, uint8_t *txbuf)
{
frame.id = FLEXCAN_ID_STD(id);
frame.format = (uint8_t)kFLEXCAN_FrameFormatStandard;
frame.type = (uint8_t)kFLEXCAN_FrameTypeData;
frame.length = (uint8_t)DLC;
#if (defined(USE_CANFD) && USE_CANFD)
frame.brs = 1U;
frame.edl = 1U;
#endif
txXfer.mbIdx = (uint8_t)TX_MESSAGE_BUFFER_NUM;
#if (defined(USE_CANFD) && USE_CANFD)
txXfer.framefd = &frame;
(void)FLEXCAN_TransferFDSendNonBlocking(EXAMPLE_CAN, &flexcanHandle, &txXfer);
#else
txXfer.frame = &frame;
frame.dataByte0 = txbuf[0];
frame.dataByte1 = txbuf[1];
frame.dataByte2 = txbuf[2];
frame.dataByte3 = txbuf[3];
frame.dataByte4 = txbuf[4];
frame.dataByte5 = txbuf[5];
frame.dataByte6 = txbuf[6];
frame.dataByte7 = txbuf[7];
(void)FLEXCAN_TransferSendNonBlocking(EXAMPLE_CAN, &flexcanHandle, &txXfer);
#endif
while (!txComplete)
{
};
txComplete = false;
}
void init_can(void)
{
flexcan_config_t flexcanConfig;
flexcan_rx_mb_config_t mbConfig;
uint8_t node_type;
rxIdentifier = 0x506;
FLEXCAN_GetDefaultConfig(&flexcanConfig);
flexcanConfig.bitRate = 500000U;
#if defined(EXAMPLE_CAN_CLK_SOURCE)
flexcanConfig.clkSrc = EXAMPLE_CAN_CLK_SOURCE;
#endif
#if defined(EXAMPLE_CAN_BIT_RATE)
flexcanConfig.bitRate = EXAMPLE_CAN_BIT_RATE;
#endif
/* If special quantum setting is needed, set the timing parameters. */
#if (defined(SET_CAN_QUANTUM) && SET_CAN_QUANTUM)
flexcanConfig.timingConfig.phaseSeg1 = PSEG1;
flexcanConfig.timingConfig.phaseSeg2 = PSEG2;
flexcanConfig.timingConfig.propSeg = PROPSEG;
#if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
flexcanConfig.timingConfig.fphaseSeg1 = FPSEG1;
flexcanConfig.timingConfig.fphaseSeg2 = FPSEG2;
flexcanConfig.timingConfig.fpropSeg = FPROPSEG;
#endif
#endif
#if (defined(USE_IMPROVED_TIMING_CONFIG) && USE_IMPROVED_TIMING_CONFIG)
flexcan_timing_config_t timing_config;
memset(&timing_config, 0, sizeof(flexcan_timing_config_t));
#if (defined(USE_CANFD) && USE_CANFD)
if (FLEXCAN_FDCalculateImprovedTimingValues(EXAMPLE_CAN, flexcanConfig.bitRate, flexcanConfig.bitRateFD,
EXAMPLE_CAN_CLK_FREQ, &timing_config))
{
/* Update the improved timing configuration*/
memcpy(&(flexcanConfig.timingConfig), &timing_config, sizeof(flexcan_timing_config_t));
}
else
{
LOG_INFO("No found Improved Timing Configuration. Just used default configuration\r\n\r\n");
}
#else
if (FLEXCAN_CalculateImprovedTimingValues(EXAMPLE_CAN, flexcanConfig.bitRate, EXAMPLE_CAN_CLK_FREQ, &timing_config))
{
/* Update the improved timing configuration*/
memcpy(&(flexcanConfig.timingConfig), &timing_config, sizeof(flexcan_timing_config_t));
}
else
{
LOG_INFO("No found Improved Timing Configuration. Just used default configuration\r\n\r\n");
}
#endif
#endif
#if (defined(USE_CANFD) && USE_CANFD)
FLEXCAN_FDInit(EXAMPLE_CAN, &flexcanConfig, EXAMPLE_CAN_CLK_FREQ, BYTES_IN_MB, true);
#else
FLEXCAN_Init(EXAMPLE_CAN, &flexcanConfig, EXAMPLE_CAN_CLK_FREQ);
#endif
/* Create FlexCAN handle structure and set call back function. */
FLEXCAN_TransferCreateHandle(EXAMPLE_CAN, &flexcanHandle, flexcan_callback, NULL);
/* Set Rx Masking mechanism. */
FLEXCAN_SetRxMbGlobalMask(EXAMPLE_CAN, FLEXCAN_RX_MB_STD_MASK(rxIdentifier, 0, 0));
/* Setup Rx Message Buffer. */
mbConfig.format = kFLEXCAN_FrameFormatStandard;
mbConfig.type = kFLEXCAN_FrameTypeData;
mbConfig.id = FLEXCAN_ID_STD(rxIdentifier);
#if (defined(USE_CANFD) && USE_CANFD)
FLEXCAN_SetFDRxMbConfig(EXAMPLE_CAN, RX_MESSAGE_BUFFER_NUM, &mbConfig, true);
#else
FLEXCAN_SetRxMbConfig(EXAMPLE_CAN, RX_MESSAGE_BUFFER_NUM, &mbConfig, true);
#endif
/* Setup Tx Message Buffer. */
#if (defined(USE_CANFD) && USE_CANFD)
FLEXCAN_SetFDTxMbConfig(EXAMPLE_CAN, TX_MESSAGE_BUFFER_NUM, true);
#else
FLEXCAN_SetTxMbConfig(EXAMPLE_CAN, TX_MESSAGE_BUFFER_NUM, true);
#endif
/* Configure CAN transceiver */
FLEXCAN_PHY_Config();
}
3.2、can.h
#ifndef __CAN_H
#define __CAN_H
#define USE_CANFD (0)
#define EXAMPLE_CAN CAN0
#define RX_MESSAGE_BUFFER_NUM (0)
#define TX_MESSAGE_BUFFER_NUM (1)
#define EXAMPLE_CAN_CLK_FREQ CLOCK_GetFlexcanClkFreq(0U)
#define USE_IMPROVED_TIMING_CONFIG (1)
#define LOG_INFO (void)PRINTF
void init_can(void);
void can_std_tx(uint32_t id, uint8_t *txbuf);
uint8_t can_rx_hdl(uint8_t *rxbuf);
#endif
3.3、main.c
#include "main.h"
int main(void)
{
uint8_t can_tx_buf[8];
uint8_t can_rx_buf[8];
uint8_t i;
CLOCK_EnableClock(kCLOCK_Gpio0);
BOARD_InitDEBUG_UARTPins();
BOARD_PowerMode_OD();
BOARD_InitBootPins();
BOARD_InitBootClocks();
BOARD_InitDebugConsole();
SysTick_Init();
init_led();
init_can();
while (1)
{
if(can_rx_hdl(can_rx_buf))
{
can_std_tx((uint32_t)0x510,can_rx_buf);
}
}
}
四、运行结果
4.1、CAN0收发数据
4.2、串口打印接收的数据
五、附件
测试源代码:
-
回复了主题帖:
【兆易GD32H759I-EVAL】ADC测试
zz19940910 发表于 2025-1-8 10:10
我在pc2上给了一个1.2v电压 为什么采集不到数据呢
ADC端口配置正常?
- 2024-12-27
-
回复了主题帖:
【FRDM-MCXN947】TFT-LCD显示屏测试
秦天qintian0303 发表于 2024-12-27 11:03
你这是做了转接板吗,看着好像直接连上去的
做的转接板,驱动一个老旧屏幕
-
回复了主题帖:
【FRDM-MCXN947】TFT-LCD显示屏测试
秦天qintian0303 发表于 2024-12-25 22:53
这个要是有那个官方的模块效果会不会更好,省的配置了
嗯,想通过MCLCD接口的配置的学习来了解这个接口方面的应用。
- 2024-12-24
-
发表了主题帖:
【FRDM-MCXN947】移植LVGL
本帖最后由 TL-LED 于 2024-12-24 00:48 编辑
移植LVGL到开发板,在FreeRTOS系统基础上进行移植。
一、下载LVGL源码
下载V8.3版本
下载地址:https://github.com/lvgl/lvgl/tree/release/v8.3
二、添加文件到工程
将下载的LVGL源码文件复制到工程目录middleware\lvgl下,添加文件到工程中
三、源码部分
显示屏驱动程序参考例程FRDM-MCXN947\SDK_2_16_100_FRDM-MCXN947\boards\frdmmcxn947\lvgl_examples中的代码
3.1、lvgl_support.c
/*
* Copyright 2023 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "lvgl_support.h"
#include "lvgl.h"
#if defined(SDK_OS_FREE_RTOS)
#include "FreeRTOS.h"
#include "semphr.h"
#endif
#include "board.h"
#include "fsl_gpio.h"
#if BOARD_USE_FLEXIO_SMARTDMA
#include "fsl_dbi_flexio_smartdma.h"
#else
#include "fsl_dbi_flexio_edma.h"
#endif
#include "fsl_flexio_mculcd.h"
#include "fsl_lpi2c.h"
#include "fsl_port.h"
#if BOARD_LCD_S035
#include "fsl_st7796s.h"
#include "fsl_gt911.h"
#else
#include "fsl_ssd1963.h"
#include "fsl_ft5406_rt.h"
#endif
#include "fsl_debug_console.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* Port Me. Start */
#if BOARD_LCD_S035
#else
#define BOARD_SSD1963_XTAL_FREQ 10000000U
#define BOARD_SSD1963_PCLK_FREQ 25000000U//30000000U
#define BOARD_SSD1963_HSW 1U//48U
#define BOARD_SSD1963_HFP 116//40U
#define BOARD_SSD1963_HBP 44//0U
#define BOARD_SSD1963_VSW 1U//3U
#define BOARD_SSD1963_VFP 10U/13U
#define BOARD_SSD1963_VBP 34U//18U
#define BOARD_SSD1963_POLARITY_FLAG 0U
#endif
/* Macros for FlexIO interfacing the LCD */
#define BOARD_FLEXIO FLEXIO0
#define BOARD_FLEXIO_CLOCK_FREQ CLOCK_GetFlexioClkFreq()
#define BOARD_FLEXIO_BAUDRATE_BPS 160000000U
/* Macros for FlexIO shifter, timer, and pins. */
#define BOARD_FLEXIO_WR_PIN 1
#define BOARD_FLEXIO_RD_PIN 0
#define BOARD_FLEXIO_DATA_PIN_START 16
#define BOARD_FLEXIO_TX_START_SHIFTER 0
#define BOARD_FLEXIO_RX_START_SHIFTER 0
#define BOARD_FLEXIO_TX_END_SHIFTER 7
#define BOARD_FLEXIO_RX_END_SHIFTER 7
#define BOARD_FLEXIO_TIMER 0
/* Macros for the touch touch controller. */
#define BOARD_TOUCH_I2C LPI2C2
#define BOARD_TOUCH_I2C_CLOCK_FREQ CLOCK_GetLPFlexCommClkFreq(2u)
#define BOARD_TOUCH_I2C_BAUDRATE 100000U
/* Port Me. End */
#define DEMO_MS_TO_TICK(ms) ((ms * configTICK_RATE_HZ / 1000) + 1)
/*******************************************************************************
* Prototypes
******************************************************************************/
static void DEMO_InitLcd(void);
static void DEMO_InitLcdClock(void);
static status_t DEMO_InitLcdController(void);
static void DEMO_FlushDisplay(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p);
static void DEMO_InitTouch(void);
static void DEMO_ReadTouch(lv_indev_drv_t *drv, lv_indev_data_t *data);
static void DEMO_SetCSPin(bool set);
static void DEMO_SetRSPin(bool set);
/*******************************************************************************
* Variables
******************************************************************************/
#if BOARD_LCD_S035
static gt911_handle_t touchHandle;
#else
static ft5406_rt_handle_t touchHandle;
#endif
#if defined(SDK_OS_FREE_RTOS)
static SemaphoreHandle_t s_memWriteDone;
#else
static volatile bool s_memWriteDone;
#endif
#if BOARD_LCD_S035
/* ST7796S LCD controller handle. */
st7796s_handle_t lcdHandle;
#else
/* SSD1963 LCD controller handle. */
ssd1963_handle_t lcdHandle;
#endif
/* DBI XFER handle. */
#if BOARD_USE_FLEXIO_SMARTDMA
dbi_flexio_smartdma_xfer_handle_t g_dbiFlexioXferHandle;
#else
dbi_flexio_edma_xfer_handle_t g_dbiFlexioXferHandle;
#endif
/* The FlexIO MCU LCD device. */
FLEXIO_MCULCD_Type flexioLcdDev = {
.flexioBase = BOARD_FLEXIO,
.busType = kFLEXIO_MCULCD_8080,
.dataPinStartIndex = BOARD_FLEXIO_DATA_PIN_START,
.ENWRPinIndex = BOARD_FLEXIO_WR_PIN,
.RDPinIndex = BOARD_FLEXIO_RD_PIN,
.txShifterStartIndex = BOARD_FLEXIO_TX_START_SHIFTER,
.txShifterEndIndex = BOARD_FLEXIO_TX_END_SHIFTER,
.rxShifterStartIndex = BOARD_FLEXIO_RX_START_SHIFTER,
.rxShifterEndIndex = BOARD_FLEXIO_RX_END_SHIFTER,
.timerIndex = BOARD_FLEXIO_TIMER,
.setCSPin = DEMO_SetCSPin,
.setRSPin = DEMO_SetRSPin,
.setRDWRPin = NULL /* Not used in 8080 mode. */
};
SDK_ALIGN(static uint8_t s_frameBuffer[2][LCD_VIRTUAL_BUF_SIZE * LCD_FB_BYTE_PER_PIXEL], 4);
/*******************************************************************************
* Code
******************************************************************************/
static void DEMO_SetCSPin(bool set)
{
GPIO_PinWrite(BOARD_LCD_CS_GPIO, BOARD_LCD_CS_PIN, (uint8_t)set);
}
static void DEMO_SetRSPin(bool set)
{
GPIO_PinWrite(BOARD_LCD_RS_GPIO, BOARD_LCD_RS_PIN, (uint8_t)set);
}
static void DEMO_DbiMemoryDoneCallback(status_t status, void *userData)
{
#if defined(SDK_OS_FREE_RTOS)
BaseType_t taskAwake = pdFALSE;
xSemaphoreGiveFromISR(s_memWriteDone, &taskAwake);
portYIELD_FROM_ISR(taskAwake);
#else
s_memWriteDone = true;
#endif
}
#if BOARD_LCD_S035
void DEMO_LCD_I2C_Init(void)
{
BOARD_LPI2C_Init(BOARD_TOUCH_I2C, BOARD_TOUCH_I2C_CLOCK_FREQ);
}
status_t DEMO_LCD_I2C_Send(
uint8_t deviceAddress, uint32_t subAddress, uint8_t subaddressSize, const uint8_t *txBuff, uint8_t txBuffSize)
{
return BOARD_LPI2C_Send(BOARD_TOUCH_I2C, deviceAddress, subAddress, subaddressSize, (uint8_t *)txBuff, txBuffSize);
}
status_t DEMO_LCD_I2C_Receive(
uint8_t deviceAddress, uint32_t subAddress, uint8_t subaddressSize, uint8_t *rxBuff, uint8_t rxBuffSize)
{
return BOARD_LPI2C_Receive(BOARD_TOUCH_I2C, deviceAddress, subAddress, subaddressSize, rxBuff, rxBuffSize);
}
void DEMO_TouchDelayMs(uint32_t delayMs)
{
#if defined(SDK_OS_FREE_RTOS)
vTaskDelay(pdMS_TO_TICKS(delayMs));
#else
SDK_DelayAtLeastUs(delayMs * 1000, CLOCK_GetCoreSysClkFreq());
#endif
}
void DEMO_TouchConfigIntPin(gt911_int_pin_mode_t mode)
{
port_pin_config_t int_config = {/* Internal pull-up/down resistor is disabled */
kPORT_PullDown,
/* Low internal pull resistor value is selected. */
kPORT_LowPullResistor,
/* Fast slew rate is configured */
kPORT_FastSlewRate,
/* Passive input filter is disabled */
kPORT_PassiveFilterDisable,
/* Open drain output is disabled */
kPORT_OpenDrainDisable,
/* Low drive strength is configured */
kPORT_LowDriveStrength,
/* Pin is configured as GPIO */
kPORT_MuxAlt0,
/* Digital input enabled */
kPORT_InputBufferEnable,
/* Digital input is not inverted */
kPORT_InputNormal,
/* Pin Control Register fields [15:0] are not locked */
kPORT_UnlockRegister};
switch (mode)
{
case kGT911_IntPinPullUp:
int_config.pullSelect = kPORT_PullUp;
break;
case kGT911_IntPinPullDown:
int_config.pullSelect = kPORT_PullDown;
break;
case kGT911_IntPinInput:
int_config.pullSelect = kPORT_PullDisable;
break;
default:
break;
};
PORT_SetPinConfig(BOARD_LCD_INT_PORT, BOARD_LCD_INT_PIN, &int_config);
}
void DEMO_TouchConfigResetPin(bool pullUp)
{
/*
* As touch controller and display controller shares the same reset pin,
* we do not do actual reset / address configuration here. Please check below for
* the relationship between RST pin and INT pin.
*
*/
}
#endif
/* Clear the LCD controller video memory content. */
static void DEMO_ClearLcd(void)
{
int32_t leftLinesToClear = LCD_HEIGHT;
int32_t curLinesToClear;
int32_t startLine = 0;
while (leftLinesToClear > 0)
{
curLinesToClear =
(leftLinesToClear > (2 * LCD_VIRTUAL_BUF_HEIGHT)) ? (2 * LCD_VIRTUAL_BUF_HEIGHT) : leftLinesToClear;
#if BOARD_LCD_S035
ST7796S_SelectArea(&lcdHandle, 0, startLine, LCD_WIDTH - 1, startLine + curLinesToClear - 1);
#else
SSD1963_SelectArea(&lcdHandle, 0, startLine, LCD_WIDTH - 1, startLine + curLinesToClear - 1);
#endif
#if !defined(SDK_OS_FREE_RTOS)
s_memWriteDone = false;
#endif
#if BOARD_LCD_S035
ST7796S_WritePixels(&lcdHandle, (uint16_t *)s_frameBuffer, curLinesToClear * LCD_WIDTH);
#else
SSD1963_WriteMemory(&lcdHandle, (const uint8_t *)s_frameBuffer,
curLinesToClear * LCD_WIDTH * LCD_FB_BYTE_PER_PIXEL);
#endif
#if defined(SDK_OS_FREE_RTOS)
if (xSemaphoreTake(s_memWriteDone, portMAX_DELAY) != pdTRUE)
{
PRINTF("Wait semaphore error: s_memWriteDone\r\n");
assert(0);
}
#else
while (false == s_memWriteDone)
{
}
#endif
startLine += curLinesToClear;
leftLinesToClear -= curLinesToClear;
}
}
status_t DEMO_InitLcdController(void)
{
status_t status;
flexio_mculcd_config_t flexioMcuLcdConfig;
#if BOARD_LCD_S035
const st7796s_config_t st7796sConfig = {.driverPreset = kST7796S_DriverPresetLCDPARS035,
.pixelFormat = kST7796S_PixelFormatRGB565,
.orientationMode = kST7796S_Orientation270,
.teConfig = kST7796S_TEDisabled,
.invertDisplay = true,
.flipDisplay = true,
.bgrFilter = true};
#else
const ssd1963_config_t ssd1963Config = {.pclkFreq_Hz = BOARD_SSD1963_PCLK_FREQ,
.pixelInterface = kSSD1963_RGB565,
.panelDataWidth = kSSD1963_PanelData18Bit,
.polarityFlags = BOARD_SSD1963_POLARITY_FLAG,
.panelWidth = LCD_WIDTH,
.panelHeight = LCD_HEIGHT,
.hsw = BOARD_SSD1963_HSW,
.hfp = BOARD_SSD1963_HFP,
.hbp = BOARD_SSD1963_HBP,
.vsw = BOARD_SSD1963_VSW,
.vfp = BOARD_SSD1963_VFP,
.vbp = BOARD_SSD1963_VBP};
#endif
const gpio_pin_config_t pinConfig = {
.pinDirection = kGPIO_DigitalOutput,
.outputLogic = 1,
};
#if BOARD_USE_FLEXIO_SMARTDMA
flexio_mculcd_smartdma_config_t flexioEzhConfig = {
.inputPixelFormat = kFLEXIO_MCULCD_RGB565,
.outputPixelFormat = kFLEXIO_MCULCD_RGB565,
};
#endif
/* Set SSD1963 CS, RS, and reset pin to output. */
GPIO_PinInit(BOARD_LCD_RST_GPIO, BOARD_LCD_RST_PIN, &pinConfig);
GPIO_PinInit(BOARD_LCD_CS_GPIO, BOARD_LCD_CS_PIN, &pinConfig);
GPIO_PinInit(BOARD_LCD_RS_GPIO, BOARD_LCD_RS_PIN, &pinConfig);
/* Initialize the flexio MCU LCD. */
/*
* flexioMcuLcdConfig.enable = true;
* flexioMcuLcdConfig.enableInDoze = false;
* flexioMcuLcdConfig.enableInDebug = true;
* flexioMcuLcdConfig.enableFastAccess = true;
* flexioMcuLcdConfig.baudRate_Bps = 96000000U;
*/
FLEXIO_MCULCD_GetDefaultConfig(&flexioMcuLcdConfig);
flexioMcuLcdConfig.baudRate_Bps = BOARD_FLEXIO_BAUDRATE_BPS;
status = FLEXIO_MCULCD_Init(&flexioLcdDev, &flexioMcuLcdConfig, BOARD_FLEXIO_CLOCK_FREQ);
if (kStatus_Success != status)
{
return status;
}
#if BOARD_USE_FLEXIO_SMARTDMA
/* Create the DBI XFER handle. */
status = DBI_FLEXIO_SMARTDMA_CreateXferHandle(&g_dbiFlexioXferHandle, &flexioLcdDev, &flexioEzhConfig);
#else
/* Create the DBI XFER handle. Because DMA transfer is not used, so don't
* need to create DMA handle.
*/
status = DBI_FLEXIO_EDMA_CreateXferHandle(&g_dbiFlexioXferHandle, &flexioLcdDev, NULL, NULL);
#endif
if (kStatus_Success != status)
{
return status;
}
/* Reset the SSD1963 LCD controller. */
GPIO_PinWrite(BOARD_LCD_RST_GPIO, BOARD_LCD_RST_PIN, 0);
#if BOARD_LCD_S035
/* Required for GT911 I2C address mode 0 */
DEMO_TouchConfigIntPin(kGT911_IntPinPullDown);
#endif
#if defined(SDK_OS_FREE_RTOS)
vTaskDelay(DEMO_MS_TO_TICK(1)); /* Delay at least 10ns. */
#else
SDK_DelayAtLeastUs(1000U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
#endif
GPIO_PinWrite(BOARD_LCD_RST_GPIO, BOARD_LCD_RST_PIN, 1);
#if BOARD_LCD_S035
DEMO_TouchConfigIntPin(kGT911_IntPinInput);
#endif
#if defined(SDK_OS_FREE_RTOS)
vTaskDelay(DEMO_MS_TO_TICK(5)); /* Delay at 5ms. */
#else
SDK_DelayAtLeastUs(5000U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
#endif
#if BOARD_USE_FLEXIO_SMARTDMA
#if BOARD_LCD_S035
status = ST7796S_Init(&lcdHandle, &st7796sConfig, &g_dbiFlexioSmartdmaXferOps, &g_dbiFlexioXferHandle);
#else
status = SSD1963_Init(&lcdHandle, &ssd1963Config, &g_dbiFlexioSmartdmaXferOps, &g_dbiFlexioXferHandle,
BOARD_SSD1963_XTAL_FREQ);
#endif
#else
#if BOARD_LCD_S035
status = ST7796S_Init(&lcdHandle, &st7796sConfig, &g_dbiFlexioEdmaXferOps, &g_dbiFlexioXferHandle);
#else
status = SSD1963_Init(&lcdHandle, &ssd1963Config, &g_dbiFlexioEdmaXferOps, &g_dbiFlexioXferHandle,
BOARD_SSD1963_XTAL_FREQ);
#endif
#endif
if (status == kStatus_Success)
{
#if BOARD_LCD_S035
ST7796S_SetMemoryDoneCallback(&lcdHandle, DEMO_DbiMemoryDoneCallback, NULL);
#else
SSD1963_SetMemoryDoneCallback(&lcdHandle, DEMO_DbiMemoryDoneCallback, NULL);
#endif
/* Clear the SSD1963 video ram. */
DEMO_ClearLcd();
#if BOARD_LCD_S035
ST7796S_EnableDisplay(&lcdHandle, true);
#else
SSD1963_StartDisplay(&lcdHandle);
SSD1963_SetBackLight(&lcdHandle, 128);
#endif
}
else
{
PRINTF("LCD controller initialization failed.\r\n");
}
return status;
}
static void DEMO_InitLcdClock(void)
{
}
static void DEMO_InitLcd(void)
{
#if defined(SDK_OS_FREE_RTOS)
s_memWriteDone = xSemaphoreCreateBinary();
if (NULL == s_memWriteDone)
{
PRINTF("Frame semaphore create failed\r\n");
assert(0);
}
#else
s_memWriteDone = false;
#endif
DEMO_InitLcdClock();
DEMO_InitLcdController();
}
/* Flush the content of the internal buffer the specific area on the display
* You can use DMA or any hardware acceleration to do this operation in the background but
* 'lv_flush_ready()' has to be called when finished
* This function is required only when LV_VDB_SIZE != 0 in lv_conf.h*/
static void DEMO_FlushDisplay(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
{
lv_coord_t x1 = area->x1;
lv_coord_t y1 = area->y1;
lv_coord_t x2 = area->x2;
lv_coord_t y2 = area->y2;
int32_t length = (x2 - x1 + 1) * (y2 - y1 + 1) * LCD_FB_BYTE_PER_PIXEL;
#if BOARD_LCD_S035
ST7796S_SelectArea(&lcdHandle, x1, y1, x2, y2);
#else
SSD1963_SelectArea(&lcdHandle, x1, y1, x2, y2);
#endif
#if !defined(SDK_OS_FREE_RTOS)
s_memWriteDone = false;
#endif
#if BOARD_LCD_S035
ST7796S_WritePixels(&lcdHandle, (uint16_t *)color_p, length / LCD_FB_BYTE_PER_PIXEL);
#else
SSD1963_WriteMemory(&lcdHandle, (const uint8_t *)color_p, length);
#endif
#if defined(SDK_OS_FREE_RTOS)
if (xSemaphoreTake(s_memWriteDone, portMAX_DELAY) != pdTRUE)
{
PRINTF("Wait semaphore error: s_memWriteDone\r\n");
assert(0);
}
#else
while (!s_memWriteDone)
{
}
#endif
/* IMPORTANT!!!
* Inform the graphics library that you are ready with the flushing*/
lv_disp_flush_ready(disp_drv);
}
void lv_port_pre_init(void)
{
}
void lv_port_disp_init(void)
{
static lv_disp_draw_buf_t disp_buf;
memset(s_frameBuffer, 0, sizeof(s_frameBuffer));
lv_disp_draw_buf_init(&disp_buf, (void *)s_frameBuffer[0], (void *)s_frameBuffer[1], LCD_VIRTUAL_BUF_SIZE);
/*-------------------------
* Initialize your display
* -----------------------*/
DEMO_InitLcd();
/*-----------------------------------
* Register the display in LittlevGL
*----------------------------------*/
static lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/
lv_disp_drv_init(&disp_drv); /*Basic initialization*/
/*Set up the functions to access to your display*/
/*Set the resolution of the display*/
disp_drv.hor_res = LCD_WIDTH;
disp_drv.ver_res = LCD_HEIGHT;
/*Used to copy the buffer's content to the display*/
disp_drv.flush_cb = DEMO_FlushDisplay;
/*Set a display buffer*/
disp_drv.draw_buf = &disp_buf;
/*Finally register the driver*/
lv_disp_drv_register(&disp_drv);
}
void lv_port_indev_init(void)
{
static lv_indev_drv_t indev_drv;
/*------------------
* Touchpad
* -----------------*/
/*Initialize your touchpad */
DEMO_InitTouch();
/*Register a touchpad input device*/
lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_POINTER;
indev_drv.read_cb = DEMO_ReadTouch;
lv_indev_drv_register(&indev_drv);
}
/*Initialize your touchpad*/
static void DEMO_InitTouch(void)
{
#if BOARD_LCD_S035
DEMO_LCD_I2C_Init();
gt911_config_t touchConfig = {.I2C_SendFunc = DEMO_LCD_I2C_Send,
.I2C_ReceiveFunc = DEMO_LCD_I2C_Receive,
.timeDelayMsFunc = DEMO_TouchDelayMs,
.intPinFunc = DEMO_TouchConfigIntPin,
.pullResetPinFunc = DEMO_TouchConfigResetPin,
.touchPointNum = 5,
.i2cAddrMode = kGT911_I2cAddrMode0,
.intTrigMode = kGT911_IntFallingEdge};
GT911_Init(&touchHandle, &touchConfig);
#else
lpi2c_master_config_t masterConfig;
/*
* masterConfig.enableMaster = true;
* masterConfig.baudRate_Bps = 100000U;
* masterConfig.enableTimeout = false;
*/
LPI2C_MasterGetDefaultConfig(&masterConfig);
/* Change the default baudrate configuration */
masterConfig.baudRate_Hz = BOARD_TOUCH_I2C_BAUDRATE;
/* Initialize the I2C master peripheral */
LPI2C_MasterInit(BOARD_TOUCH_I2C, &masterConfig, BOARD_TOUCH_I2C_CLOCK_FREQ);
/* Initialize the touch handle. */
FT5406_RT_Init(&touchHandle, BOARD_TOUCH_I2C);
#endif
}
/* Will be called by the library to read the touchpad */
static void DEMO_ReadTouch(lv_indev_drv_t *drv, lv_indev_data_t *data)
{
#if BOARD_LCD_S035
touch_point_t tp[5];
uint8_t tp_count = 5;
GT911_GetMultiTouch(&touchHandle, &tp_count, tp);
/**
* GT911 supports 5 points tracking, we only tracks ID #0.
*
*/
bool found_track = false;
for (uint8_t i = 0; i < tp_count; i++)
{
/* Found track ID #0 */
if (tp[i].touchID == 0)
{
data->state = LV_INDEV_STATE_PRESSED;
switch (lcdHandle.orientationMode)
{
case kST7796S_Orientation0:
data->point.x = (int16_t)tp[i].x;
data->point.y = (int16_t)tp[i].y;
break;
case kST7796S_Orientation90:
data->point.x = (int16_t)(touchHandle.resolutionY - tp[i].y);
data->point.y = (int16_t)tp[i].x;
break;
case kST7796S_Orientation180:
data->point.x = (int16_t)(touchHandle.resolutionX - tp[i].x);
data->point.y = (int16_t)(touchHandle.resolutionY - tp[i].y);
break;
case kST7796S_Orientation270:
data->point.x = (int16_t)tp[i].y;
data->point.y = (int16_t)(touchHandle.resolutionX - tp[i].x);
break;
default:
break;
}
found_track = true;
break;
}
}
/* No track #0 found... */
if (!found_track)
{
data->state = LV_INDEV_STATE_RELEASED;
}
#else
touch_event_t touch_event;
static int touch_x = 0;
static int touch_y = 0;
data->state = LV_INDEV_STATE_REL;
if (kStatus_Success == FT5406_RT_GetSingleTouch(&touchHandle, &touch_event, &touch_x, &touch_y))
{
if ((touch_event == kTouch_Down) || (touch_event == kTouch_Contact))
{
data->state = LV_INDEV_STATE_PR;
}
}
/*Set the last pressed coordinates*/
data->point.y = touch_y;
data->point.x = touch_x;
#endif
}
3.2、fun_task.c
#include "main.h"
static volatile bool s_lvgl_initialized = false;
#define START_TASK_PRO tskIDLE_PRIORITY + 1
#define START_STK_SIZE 256
TaskHandle_t StartTask_Handler;
#define TASK1_PRIO tskIDLE_PRIORITY + 2
#define TASK1_STK_SIZE 256
static TaskHandle_t Task1Task_Handler = NULL;
#define TASK2_PRIO tskIDLE_PRIORITY + 3
#define TASK2_STK_SIZE 256
static TaskHandle_t Task2Task_Handler = NULL;
#define TASK3_PRIO tskIDLE_PRIORITY + 4
#define TASK3_STK_SIZE configMINIMAL_STACK_SIZE + 800
static TaskHandle_t Task3Task_Handler = NULL;
void start_task(void *pvParameters);
void task1(void *pvParameters);
void task2(void *pvParameters);
void task3(void *pvParameters);
void task_create(void)
{
//start_task
xTaskCreate((TaskFunction_t )start_task,
(const char* )"start_task",
(uint16_t )START_STK_SIZE,
(void* )NULL,
(UBaseType_t )START_TASK_PRO,
(TaskHandle_t* )&StartTask_Handler);
vTaskStartScheduler();
}
void start_task(void *pvParameters)
{
taskENTER_CRITICAL();
//task1
xTaskCreate((TaskFunction_t )task1,
(const char* )"task1",
(uint16_t )TASK1_STK_SIZE,
(void* )NULL,
(UBaseType_t )TASK1_PRIO,
(TaskHandle_t* )&Task1Task_Handler);
//task2
xTaskCreate((TaskFunction_t )task2,
(const char* )"task2",
(uint16_t )TASK2_STK_SIZE,
(void* )NULL,
(UBaseType_t )TASK2_PRIO,
(TaskHandle_t* )&Task2Task_Handler);
//task3-lvlg
xTaskCreate((TaskFunction_t )task3,
(const char* )"task3",
(uint16_t )TASK3_STK_SIZE,
(void* )NULL,
(UBaseType_t )TASK3_PRIO,
(TaskHandle_t* )&Task2Task_Handler);
taskEXIT_CRITICAL();
vTaskDelete(StartTask_Handler);
}
//task1
void task1(void *pvParameters)
{
__IO uint32_t index = 0;
__IO uint32_t flash_id_index = 0;
// tx_data_fill();
// spiflash_init();
// flash_id_index = spiflash_read_id();
// if(flash_id_index !=0x5114)
// {
// PRINTF("flash id check error!\r\n");
// }
// else
// {
// PRINTF("flash id check success! id: %x\r\n", flash_id_index);
// }
//
// spiflash_sector_erase(FLASH_TEST_ADDR / SPIF_SECTOR_SIZE);
// spiflash_write(tx_buffer, FLASH_TEST_ADDR, SPI_BUF_SIZE);
// spiflash_read(rx_buffer, FLASH_TEST_ADDR, SPI_BUF_SIZE);
// PRINTF("Read Data: ");
// for(index = 0; index < SPI_BUF_SIZE; index++)
// {
// PRINTF("%x ", rx_buffer[index]);
// }
while (1)
{
PRINTF("task1 run ...\r\n");
vTaskDelay(200);
}
}
//task2
void task2(void *pvParameters)
{
while (1)
{
PRINTF("task2 run ...\r\n");
vTaskDelay(100);
}
}
//task3
void task3(void *pvParameters)
{
lv_port_pre_init();
lv_init();S
lv_port_disp_init();
//lv_port_indev_init();
s_lvgl_initialized = true;
lv_demo_benchmark();
while (1)
{
lv_task_handler();
led_red_tog();
vTaskDelay(5);
}
}
/*!
* [url=home.php?mod=space&uid=159083]@brief[/url] FreeRTOS tick hook.
*/
void vApplicationTickHook(void)
{
if (s_lvgl_initialized)
{
lv_tick_inc(1);
}
}
/*!
* @brief Malloc failed hook.
*/
void vApplicationMallocFailedHook(void)
{
PRINTF("Malloc failed. Increase the heap size.");
for (;;)
;
}
/*!
* @brief Stack overflow hook.
*/
void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName)
{
(void)pcTaskName;
(void)xTask;
for (;;)
;
}
3.3、main.c
#include "main.h"
static void BOARD_InitSmartDMA(void);
int main(void)
{
uint8_t i;
CLOCK_EnableClock(kCLOCK_Gpio0);
BOARD_InitDEBUG_UARTPins();
BOARD_PowerMode_OD();
BOARD_InitBootPins();
BOARD_InitBootClocks();
BOARD_InitDebugConsole();
BOARD_InitSmartDMA();
init_led();
init_key();
task_create();
while (1)
{
}
}
static void BOARD_InitSmartDMA(void)
{
RESET_ClearPeripheralReset(kMUX_RST_SHIFT_RSTn);
INPUTMUX_Init(INPUTMUX0);
INPUTMUX_AttachSignal(INPUTMUX0, 0, kINPUTMUX_FlexioToSmartDma);
/* Turnoff clock to inputmux to save power. Clock is only needed to make changes */
INPUTMUX_Deinit(INPUTMUX0);
SMARTDMA_InitWithoutFirmware();
NVIC_EnableIRQ(SMARTDMA_IRQn);
NVIC_SetPriority(SMARTDMA_IRQn, 3);
}
四、程序运行
下载程序到开发板后,显示屏显示如下:
[localvideo]43de8b1f1ac9d1df8dff2fab4ea63801[/localvideo]
- 2024-12-23
-
回复了主题帖:
【FRDM-MCXN947】TFT-LCD显示屏测试
bigbat 发表于 2024-12-23 09:40
感觉楼主的速度有点慢,是不是楼主程序有延时。
小窗口循环显示有延时
- 2024-12-22
-
发表了主题帖:
【FRDM-MCXN947】TFT-LCD显示屏测试
本帖最后由 TL-LED 于 2024-12-22 22:50 编辑
使用FLEXIO接口测试TFT-LCD显示屏,驱动芯片使用SSD1963。
一、硬件接口部分
1.1、使用板子上的LCD接口
1.2、SSD1963接口框图
1.3、SSD1963数据格式
SSD1963与显示屏之间数据接口的连接定义
1.4、显示屏接口
我的显示屏是18位总线,在配置SSD1963时,选择18位数据。
二、引脚配置
2.1、配置显示屏接口
2.2、配置外设
三、程序部分
3.1、mculcd.c
#include "main.h"
/*******************************************************************************
* Prototypes
******************************************************************************/
void BOARD_InitSmartDMA(void);
static void DEMO_InitFlexioMcuLcd(void);
static void DEMO_InitPanel(void);
static void DEMO_StartPanel(void);
static status_t DEMO_LcdWriteCommand(void *dbiXferHandle, uint32_t command);
static status_t DEMO_LcdWriteData(void *dbiXferHandle, void *data, uint32_t len_byte);
static status_t DEMO_LcdWriteMemory(void *dbiXferHandle, uint32_t command, const void *data, uint32_t len_byte);
/*******************************************************************************
* Variables
******************************************************************************/
/* The functions used to drive the panel. */
static dbi_xfer_ops_t s_flexioDbiOps = {
.writeCommand = DEMO_LcdWriteCommand,
.writeData = DEMO_LcdWriteData,
.writeMemory = DEMO_LcdWriteMemory,
.readMemory = NULL, /* Don't need read in this project. */
.setMemoryDoneCallback = NULL, /* This used for upper layer to register callback.
If the writeMemory is a non-blocking(or async)
function, when write finished, the registered
callback function will be called.
In this project, to be simple, DEMO_LcdWriteMemory
blocks to wait the write done, it is not async
implementation, so don't need to set callback.
*/
};
static ssd1963_handle_t lcdHandle;
static flexio_mculcd_smartdma_handle_t s_flexioLcdHandle;
static demo_pixel_t s_lcdBuffer[DEMO_BUFFER_HEIGHT][DEMO_BUFFER_WIDTH];
static volatile bool s_transferDone = false;
void FLEXIO_TransferCallback(FLEXIO_MCULCD_Type *,flexio_mculcd_smartdma_handle_t *,status_t ,void *)
{
s_transferDone = true;
}
void BOARD_SetResetPin(bool set)
{
GPIO_PinWrite(DEMO_SSD1963_RST_GPIO, DEMO_SSD1963_RST_PIN, (uint8_t)set);
}
void BOARD_InitSmartDMA(void)
{
RESET_ClearPeripheralReset(kMUX_RST_SHIFT_RSTn);
INPUTMUX_Init(INPUTMUX0);
INPUTMUX_AttachSignal(INPUTMUX0, 0, kINPUTMUX_FlexioToSmartDma);
/* Turnoff clock to inputmux to save power. Clock is only needed to make changes */
INPUTMUX_Deinit(INPUTMUX0);
SMARTDMA_InitWithoutFirmware();
NVIC_EnableIRQ(SMARTDMA_IRQn);
NVIC_SetPriority(SMARTDMA_IRQn, 3);
}
static status_t DEMO_LcdWriteCommand(void *dbiXferHandle, uint32_t command)
{
/* dbiXferHandle is actually s_flexioLcdHandle, set by SSD1963_Init 4th parameter. */
flexio_mculcd_smartdma_handle_t *flexioLcdHandle = (flexio_mculcd_smartdma_handle_t *)dbiXferHandle;
/* Here use blocking way to send command, because command is short. */
FLEXIO_MCULCD_Type *flexioLCD = flexioLcdHandle->base; /* flexioLcdDev */
FLEXIO_MCULCD_StartTransfer(flexioLCD);
FLEXIO_MCULCD_WriteCommandBlocking(flexioLCD, command);
FLEXIO_MCULCD_StopTransfer(flexioLCD);
return kStatus_Success;
}
static status_t DEMO_LcdWriteData(void *dbiXferHandle, void *data, uint32_t len_byte)
{
/* dbiXferHandle is actually s_flexioLcdHandle, set by SSD1963_Init 4th parameter. */
flexio_mculcd_smartdma_handle_t *flexioLcdHandle = (flexio_mculcd_smartdma_handle_t *)dbiXferHandle;
/*
* Here use blocking way to write data, this function is generally
* used to send command parameter, the data length is short.
*/
FLEXIO_MCULCD_Type *flexioLCD = flexioLcdHandle->base; /* flexioLcdDev */
FLEXIO_MCULCD_StartTransfer(flexioLCD);
FLEXIO_MCULCD_WriteDataArrayBlocking(flexioLCD, data, len_byte);
FLEXIO_MCULCD_StopTransfer(flexioLCD);
return kStatus_Success;
}
static status_t DEMO_LcdWriteMemory(void *dbiXferHandle, uint32_t command, const void *data, uint32_t len_byte)
{
status_t status;
/* dbiXferHandle is actually s_flexioLcdHandle, set by SSD1963_Init 4th parameter. */
flexio_mculcd_smartdma_handle_t *flexioLcdHandle = (flexio_mculcd_smartdma_handle_t *)dbiXferHandle;
FLEXIO_MCULCD_Type *flexioLCD = flexioLcdHandle->base; /* flexioLcdDev */
flexio_mculcd_transfer_t xfer = {
.command = command,
.mode = kFLEXIO_MCULCD_WriteArray,
.dataAddrOrSameValue = (uint32_t)data,
.dataSize = len_byte,
};
s_transferDone = false;
status = FLEXIO_MCULCD_TransferSMARTDMA(flexioLCD, flexioLcdHandle, &xfer);
if (kStatus_Success != status)
{
PRINTF("Write Memory Failed\r\n");
while (1)
{
}
}
else
{
/* Wait for transfer done. */
while (!s_transferDone)
{
}
}
return status;
}
static void DEMO_InitFlexioMcuLcd(void)
{
status_t status;
flexio_mculcd_config_t flexioMcuLcdConfig;
flexio_mculcd_smartdma_config_t flexioEzhConfig = {
.inputPixelFormat = kFLEXIO_MCULCD_RGB565,
.outputPixelFormat = kFLEXIO_MCULCD_RGB565,
};
/* Initialize the flexio MCU LCD. */
/*
* flexioMcuLcdConfig.enable = true;
* flexioMcuLcdConfig.enableInDoze = false;
* flexioMcuLcdConfig.enableInDebug = true;
* flexioMcuLcdConfig.enableFastAccess = true;
* flexioMcuLcdConfig.baudRate_Bps = 96000000U;
*/
// FLEXIO_MCULCD_GetDefaultConfig(&flexioMcuLcdConfig);
// flexioMcuLcdConfig.baudRate_Bps = DEMO_FLEXIO_BAUDRATE_BPS;
// status = FLEXIO_MCULCD_Init(&flexioLcdDev, &flexioMcuLcdConfig, DEMO_FLEXIO_CLOCK_FREQ);
// if (kStatus_Success != status)
// {
// PRINTF("FlexIO MCULCD init failed\r\n");
// while (1)
// ;
// }
/* Init SMARTDMA. */
// BOARD_InitSmartDMA();
// /* Create FLEXIO_MCULCD SMARTDMA handle. */
// status = FLEXIO_MCULCD_TransferCreateHandleSMARTDMA(&flexioLcdDev, &s_flexioLcdHandle, &flexioEzhConfig,
// DEMO_FLEXIO_TransferCallback, NULL);
// status = FLEXIO_MCULCD_TransferCreateHandleSMARTDMA(&FLEXIO0_peripheralConfig, &ss_flexioLcdHandle, &FLEXIO0_smartdma_config,
// FLEXIO_TransferCallback, NULL);
// if (kStatus_Success != status)
// {
// PRINTF("FlexIO MCULCD handle creation failed\r\n");
// while (1)
// ;
// }
}
static void DEMO_InitPanel(void)
{
status_t status;
const ssd1963_config_t ssd1963Config = {
.pclkFreq_Hz = DEMO_SSD1963_PCLK_FREQ,
#if SSD1963_DATA_WITDH == 16
.pixelInterface = kSSD1963_PixelInterface16Bit565,
#else
.pixelInterface = kSSD1963_PixelInterface8BitBGR888,
#endif
.panelDataWidth = kSSD1963_PanelData18Bit,
.polarityFlags = DEMO_SSD1963_POLARITY_FLAG,
.panelWidth = DEMO_PANEL_WIDTH,
.panelHeight = DEMO_PANEL_HEIGHT,
.hsw = DEMO_SSD1963_HSW,
.hfp = DEMO_SSD1963_HFP,
.hbp = DEMO_SSD1963_HBP,
.vsw = DEMO_SSD1963_VSW,
.vfp = DEMO_SSD1963_VFP,
.vbp = DEMO_SSD1963_VBP
};
/* Reset the SSD1963 LCD controller. */
BOARD_SetResetPin(false);
SDK_DelayAtLeastUs(1, SystemCoreClock); /* Delay 10ns. */
BOARD_SetResetPin(true);
SDK_DelayAtLeastUs(5000, SystemCoreClock); /* Delay 5ms. */
status = SSD1963_Init(&lcdHandle, &ssd1963Config, &s_flexioDbiOps, &ss_flexioLcdHandle, DEMO_SSD1963_XTAL_FREQ);
if (kStatus_Success != status)
{
PRINTF("Panel initialization failed\r\n");
while (1)
{
}
}
}
void DEMO_StartPanel(void)
{
SSD1963_StartDisplay(&lcdHandle);
SSD1963_SetBackLight(&lcdHandle, 255);
}
/*
* Draw one window with pixel array, and delay some time after draw done.
*/
void DEMO_DrawWindow(uint16_t startX,
uint16_t startY,
uint16_t endX,
uint16_t endY,
const uint8_t *data,
uint32_t dataLen,
uint32_t delayMsAfterDraw)
{
SSD1963_SelectArea(&lcdHandle, startX, startY, endX, endY);
SSD1963_WriteMemory(&lcdHandle, data, dataLen);
if (delayMsAfterDraw > 0)
{
SDK_DelayAtLeastUs(delayMsAfterDraw * 1000, SystemCoreClock);
}
}
/*
* Draw multiple windows with specified color, can delay some time each window draw finished.
* In this example, the whole screen is devided in to 4 windows, this function fills the
* windows one by one.
*/
void DEMO_DrawMultiWindows(demo_pixel_t color, uint32_t intervalMs)
{
/* Fill buffer with pixel. */
for (uint32_t y = 0; y < DEMO_BUFFER_HEIGHT; y++)
{
for (uint32_t x = 0; x < DEMO_BUFFER_WIDTH; x++)
{
s_lcdBuffer[y][x] = color;
}
}
/* Region 0. */
DEMO_DrawWindow(0, 0, DEMO_BUFFER_WIDTH - 1, DEMO_BUFFER_HEIGHT - 1, (const uint8_t *)s_lcdBuffer,
sizeof(s_lcdBuffer), intervalMs);
/* Region 1. */
DEMO_DrawWindow(DEMO_BUFFER_WIDTH, 0, 2 * DEMO_BUFFER_WIDTH - 1, DEMO_BUFFER_HEIGHT - 1,
(const uint8_t *)s_lcdBuffer, sizeof(s_lcdBuffer), intervalMs);
/* Region 2. */
DEMO_DrawWindow(0, DEMO_BUFFER_HEIGHT, DEMO_BUFFER_WIDTH - 1, 2 * DEMO_BUFFER_HEIGHT - 1,
(const uint8_t *)s_lcdBuffer, sizeof(s_lcdBuffer), intervalMs);
/* Region 3. */
DEMO_DrawWindow(DEMO_BUFFER_WIDTH, DEMO_BUFFER_HEIGHT, 2 * DEMO_BUFFER_WIDTH - 1, 2 * DEMO_BUFFER_HEIGHT - 1,
(const uint8_t *)s_lcdBuffer, sizeof(s_lcdBuffer), intervalMs);
}
void init_mculcd(void)
{
BOARD_InitBootPeripherals();
BOARD_InitSmartDMA();
DEMO_InitPanel();
DEMO_DrawMultiWindows(DEMO_COLOR_BLACK, 0);
DEMO_StartPanel();
}
3.2、mculcd.h
#ifndef __MCULCD_H
#define __MCULCD_H
#define DEMO_PANEL_WIDTH 640U
#define DEMO_PANEL_HEIGHT 480U
/* Macros for the LCD controller. */
#define DEMO_SSD1963_XTAL_FREQ 10000000U
#define DEMO_SSD1963_PCLK_FREQ 25000000U
#define DEMO_SSD1963_HSW 1U
#define DEMO_SSD1963_HFP 116U
#define DEMO_SSD1963_HBP 44U
#define DEMO_SSD1963_VSW 1U
#define DEMO_SSD1963_VFP 10U
#define DEMO_SSD1963_VBP 34U
#define DEMO_SSD1963_POLARITY_FLAG 0U
#define DEMO_SSD1963_RST_GPIO GPIO4
#define DEMO_SSD1963_RST_PIN 7
#define DEMO_SSD1963_CS_GPIO GPIO0
#define DEMO_SSD1963_CS_PIN 12
#define DEMO_SSD1963_RS_GPIO GPIO0
#define DEMO_SSD1963_RS_PIN 7
#define DEMO_FLEXIO FLEXIO0
#define DEMO_FLEXIO_CLOCK_FREQ CLOCK_GetFlexioClkFreq()
#define DEMO_FLEXIO_BAUDRATE_BPS 160000000U /* 16-bit data bus, baud rate on each pin is 1MHz. */
/* Macros for FlexIO shifter, timer, and pins. */
#define DEMO_FLEXIO_WR_PIN 1
#define DEMO_FLEXIO_RD_PIN 0
#define DEMO_FLEXIO_DATA_PIN_START 16
#define DEMO_FLEXIO_TX_START_SHIFTER 0
#define DEMO_FLEXIO_RX_START_SHIFTER 0
#define DEMO_FLEXIO_TX_END_SHIFTER 7
#define DEMO_FLEXIO_RX_END_SHIFTER 7
#define DEMO_FLEXIO_TIMER 0
/* Macros for DMA */
#define DEMO_EDMA DMA0
#define DEMO_FLEXIO_TX_DMA_CHANNEL 0
#define DEMO_FLEXIO_TX_DMA_REQUEST kDma0RequestMuxFlexIO0ShiftRegister0Request
/* Buffer of the LCD send data. */
#define DEMO_BUFFER_WIDTH (DEMO_PANEL_WIDTH / 2U)
#define DEMO_BUFFER_HEIGHT (DEMO_PANEL_HEIGHT / 2U)
/* Color for RGB565 */
typedef uint16_t demo_pixel_t;
#define DEMO_COLOR_RED 0xF800U
#define DEMO_COLOR_GREEN 0x07E0U
#define DEMO_COLOR_BLUE 0x001FU
#define DEMO_COLOR_WHITE 0xFFFFU
#define DEMO_COLOR_BLACK 0x0000U
void init_mculcd(void);
void DEMO_DrawWindow(uint16_t startX,
uint16_t startY,
uint16_t endX,
uint16_t endY,
const uint8_t *data,
uint32_t dataLen,
uint32_t delayMsAfterDraw);
void DEMO_DrawMultiWindows(demo_pixel_t color, uint32_t intervalMs);
#endif
3.3、main.c
#include "main.h"
int main(void)
{
uint8_t i;
uint8_t colorIdx = 0;
const demo_pixel_t colorTable[] = {
DEMO_COLOR_RED,
DEMO_COLOR_GREEN,
DEMO_COLOR_BLUE,
DEMO_COLOR_WHITE,
};
CLOCK_EnableClock(kCLOCK_Gpio0);
BOARD_InitDEBUG_UARTPins();
BOARD_PowerMode_OD();
BOARD_InitBootPins();
BOARD_InitBootClocks();
BOARD_InitDebugConsole();
SysTick_Init();
init_led();
init_key();
init_mculcd();
while (1)
{
DEMO_DrawMultiWindows(colorTable[colorIdx], 500);
colorIdx++;
if (colorIdx >= ARRAY_SIZE(colorTable))
{
colorIdx = 0U;
}
led_red_tog();
}
}
3.4、 源代码
四、运行结果
下载程序到开发板,显示屏显示如下
[localvideo]a77d775d9e1c35768f1e854c5d121424[/localvideo]