- 2025-02-21
-
回复了主题帖:
测评入围名单:航芯高性能MCU系列ACM32F403开发板
个人信息无误,确认可以完成测评计划。
- 2025-02-18
-
回复了主题帖:
【AI开发板】正点原子K230D BOX开发板来了!一款性能强悍且小巧便携的AI开发板!
真好,能给大家体验得机会就更好了!
- 2025-02-17
-
发表了主题帖:
【MCXA156开发板测评】+ TFT屏显示驱动
手头有一款MDM2802的SPI接口的显示屏,一直没弄清它的驱动芯片是啥,后来才弄清原来是十分常见的ILI9341。手头还有另一个SPI接口的显示屏,以前一直当ILI9341驱动芯片的来用,但它的驱动芯片竟是ILI9220B,
真是不免令人发笑。
那这款MDM2802显示屏与常规的SPI显示屏有啥区别呢?
那就是它居然没有D/C控制引脚,少用一个引脚就少接一条线,接省一个引脚资源呀,其引脚功能见图1所示。
图1 引脚功能
为图省事,直接用3个GPIO口就可驱动它,简直是使用I2C接口般的感觉,其引脚连接关系为:
CLK----P3_13
SDA----P3_14
CS ----P3_15
对应的连接接口为开发板上的J1,见图2所示。
图2 接口
#define CLR_CLK() GPIO_PinWrite(GPIO3,1U << 13U,0)
#define SET_CLK() GPIO_PinWrite(GPIO3,1U << 13U,1)
#define CLR_SDA() GPIO_PinWrite(GPIO3,1U << 14U,0)
#define SET_SDA() GPIO_PinWrite(GPIO3,1U << 14U,1)
#define CLR_CS() GPIO_PinWrite(GPIO3,1U << 15U,0)
#define SET_CS() GPIO_PinWrite(GPIO3,1U << 15U,1)
对所用引脚的配置函数为:
void LCD_config(void)
{
gpio_pin_config_t led_config = {
kGPIO_DigitalOutput,
0,
};
CLOCK_EnableClock(kCLOCK_GateGPIO3);
GPIO_PinInit(GPIO3, 13U, &led_config);
GPIO_PinInit(GPIO3, 14U, &led_config);
GPIO_PinInit(GPIO3, 15U, &led_config);
}
显示屏的初始化函数为:
void ili9341_init(void)
{
write_register(0xCF);
write_data(0x00);
write_data(0xC1);
write_data(0X30);
write_register(0xED);
write_data(0x64);
write_data(0x03);
write_data(0X12);
write_data(0X81);
write_register(0xE8);
write_data(0x85);
write_data(0x10);
write_data(0x7A);
write_register(0xCB);
write_data(0x39);
write_data(0x2C);
write_data(0x00);
write_data(0x34);
write_data(0x02);
write_register(0xF7);
write_data(0x20);
write_register(0xEA);
write_data(0x00);
write_data(0x00);
write_register(0xC0);
write_data(0x1B);
write_register(0xC1);
write_data(0x01);
write_register(0xC5);
write_data(0x30);
write_data(0x30);
write_register(0xC7);
write_data(0XB7);
write_register(0x36);
write_data(0x08);
write_register(0x3A);
write_data(0x55);
write_register(0xB1);
write_data(0x00);
write_data(0x1A);
write_register(0xB6);
write_data(0x0A);
write_data(0xA2);
write_register(0xF2);
write_data(0x00);
write_register(0x26);
write_data(0x01);
write_register(0xE0);
write_data(0x0F);
write_data(0x2A);
write_data(0x28);
write_data(0x08);
write_data(0x0E);
write_data(0x08);
write_data(0x54);
write_data(0XA9);
write_data(0x43);
write_data(0x0A);
write_data(0x0F);
write_data(0x00);
write_data(0x00);
write_data(0x00);
write_data(0x00);
write_register(0XE1);
write_data(0x00);
write_data(0x15);
write_data(0x17);
write_data(0x07);
write_data(0x11);
write_data(0x06);
write_data(0x2B);
write_data(0x56);
write_data(0x3C);
write_data(0x05);
write_data(0x10);
write_data(0x0F);
write_data(0x3F);
write_data(0x3F);
write_data(0x0F);
write_register(0x2B);
write_data(0x00);
write_data(0x00);
write_data(0x01);
write_data(0x3f);
write_register(0x2A);
write_data(0x00);
write_data(0x00);
write_data(0x00);
write_data(0xef);
write_register(0x11);
lcdc_delay(1000);
write_register(0x29);
}
以色彩清除屏幕的函数为:
void ili9341_clear(int c)
{
unsigned int i,j;
set_cursor(0x00, 0x0000);
gram_prepare();
for(i = 0; i < 320; i++)
{
for(j = 0; j < 240; j++)
{
write_data(c >> 8);
write_data(c);
}
}
}
实现图像显示的函数为:
void showimage(void)
{
unsigned int i,j,k;
unsigned int x=0, y=0;
k=0;
for(i=0;i<320;i++)
{
set_cursor(x,y+i);
gram_prepare();
for(j=0;j<240;j++)
{
write_data(gImage_NZ[k*2]);
write_data(gImage_NZ[k*2+1]);
k++;
}
}
}
实现驱动测试的主程序为:
int main(void)
{
RESET_ReleasePeripheralReset(kLPUART0_RST_SHIFT_RSTn);
RESET_ReleasePeripheralReset(kPORT0_RST_SHIFT_RSTn);
RESET_ReleasePeripheralReset(kPORT1_RST_SHIFT_RSTn);
RESET_ReleasePeripheralReset(kGPIO1_RST_SHIFT_RSTn);
BOARD_InitPins();
BOARD_InitBootClocks();
BOARD_InitDebugConsole();
delay();
LCD_config();
ili9341_init();
ili9341_clear(RED);
showimage();
LCD_ShowString(20,16,"MCXA156");
LCD_ShowString(82,16,"& MDM-2802");
while (1);
}
经程序的编译与下载,其测试效果如图3所示,说明驱动成功,以此为基础再添加汉字显示就更方便了。
图3 显示效果
-
回复了主题帖:
撒积分啦!!机器人开发圈公众号上线、还有多个新板块设立哦~~
新版块来了,积极支持 !
-
发表了主题帖:
【复旦微车规MCU FM32FT0A测评】仪表数据读取(3)
在进行RS485协议通讯时,多是使用相关的芯片来实现信号的转换,如芯片MAX485等。
这里所选取的一款MAX485功能模块,其原理图见图1所示。
图1功能模块电路
2个通讯节点间的连接如图2所示,各引脚的功能及用法见图3所示。此外,值得注意的是连接A、B端的导线应选用双绞线,而非常用的电源用并排直导线。
另外,当主机是台式机时,可选用RS232转RS485功能模块来充当转换单元。
图2 使用方式
图3 引脚及用法
这就回到了前面的蓝灯现象,因为在RS485的协议通讯过程中,除了收发引脚外还需要相应的辅助引脚来控制。
如发送时,需要DE引脚置高电平,而在接收时,则需将RE引脚置为低电平。
所用的蓝灯引脚就是用来控制收发的,即发送指令前,要熄灭蓝灯即输出高电平;而接收时则要点亮蓝灯,即输出输出低电平。由于从机在多数情况下是处于接收状态,故蓝色灯是点亮的。
- 2025-02-11
-
回复了主题帖:
【MCXA156开发板测评】+ 步进电机驱动与旋转LED灯
秦天qintian0303 发表于 2025-2-11 09:36
无线的方式是最好的,扩展一下,旋转的芭蕾舞者,可以参考一下这样旋转的结构
缺少一个好用的托板,只用一个纸板戳了孔套在轴上,居然能带着接收板和LED灯转起来,的确是个幸运的效果。人工有个好的托板,可用放更重些的东西。
- 2025-02-09
-
发表了主题帖:
【复旦微车规MCU FM32FT0A测评】仪表数据读取(2)
本帖最后由 jinglixixi 于 2025-2-9 17:31 编辑
在了解了流变分析仪所涉及的仪表及其使用方法的情况下,实现是以串行通讯的方式来进行程序设计及验证。
为便于指令的发送,其指令是存放在数组中,其形式如下:
uint8_t cmdQ[10]={0x3A,0x01,0x06,0x20,0x00,0x00,0x04,0xD5,0x0D,0x0A};
uint8_t cmdT[10]={0x3A,0x01,0x06,0x20,0x00,0x00,0x02,0xD7,0x0D,0x0A};
uint8_t cmdW[19]={0x02,0x30,0x32,0x31,0x57,0x30,0x34,0x30,0x30,0x30,0x2C,0x30,0x30,0x43,0x38,0x03,0xEA,0x0D,0x0A};
uint8_t cmdR[14]={0x02,0x30,0x32,0x31,0x52,0x30,0x34,0x30,0x30,0x30,0x03,0xDE,0x0D,0x0A};
以温控仪表发送读取温度为例,其指令的发送程序为:
for(i=0;i<14;i++)
{
FL_UART_WriteTXBuff(UART4,(uint8_t)cmdR[i]);
while(FL_UART_IsActiveFlag_TXBuffEmpty(UART4) != 0x01UL);
}
测试指令发送的效果如图1和图2所示。
图1 发送控制指令
图2 以字符方式指令
此外,可以将滑块分为5个区段,以对应5个指令来控制指令的发送,见图3所示。
图3 区段划分
实现指令的接收和处理,要比发送指令复杂些,以接收温度设置指令和读取温度指令为例,其主程序为:
int main(void)
{
uint8_t zl,i,f;
uint16_t w;
uint8_t cmdQ[10]={0x3A,0x01,0x06,0x20,0x00,0x00,0x04,0xD5,0x0D,0x0A};
uint8_t cmdT[10]={0x3A,0x01,0x06,0x20,0x00,0x00,0x02,0xD7,0x0D,0x0A};
uint8_t cmdW[19]={0x02,0x30,0x32,0x31,0x57,0x30,0x34,0x30,0x30,0x30,0x2C,0x30,0x30,0x43,0x38,0x03,0xEA,0x0D,0x0A};
uint8_t cmdR[14]={0x02,0x30,0x32,0x31,0x52,0x30,0x34,0x30,0x30,0x30,0x03,0xDE,0x0D,0x0A};
uint8_t cmd[20];
IWDT_Init(FL_IWDT_PERIOD_4000MS);
FL_Init();
SVD_Init(SVD_MONTIOR_VDD, FL_SVD_WARNING_THRESHOLD_GROUP11, FL_SVD_REFERENCE_1P0V);
while(false == SVD_Result_Confirmed(SVD_HIGHER_THRESHOLD, 2000U/*us*/));
RMU_BOR_Init(FL_RMU_BOR_THRESHOLD_2P00V);
MF_Config_Init();
LED_OFF(RED);
LED_OFF(GREEN);
LED_OFF(BULE);
for(i=0;i<14;i++)
{
FL_UART_WriteTXBuff(UART4,(uint8_t)cmdR[i]);
while(FL_UART_IsActiveFlag_TXBuffEmpty(UART4) != 0x01UL);
}
i=0;
LED_ON(BULE);
while(1)
{
FL_IWDT_ReloadCounter(IWDT);
PowerDownMonitoring();
if (0x01UL == FL_UART_IsActiveFlag_RXBuffFull(UART4))
{
zl = (uint8_t)FL_UART_ReadRXBuff(UART4);
}
if(zl==0x02) // 温控仪
{
i=0;
f=1;
while(f)
{
if (0x01UL == FL_UART_IsActiveFlag_RXBuffFull(UART4))
{
zl = (uint8_t)FL_UART_ReadRXBuff(UART4);
cmd[i]=zl;
i=i+1;
}
if(zl==0x0A)
{
f=0;
}
}
if(cmd[3]==0x52)
{
w=100;
LED_OFF(BULE);
printf("r=%d \r\n",w);
LED_ON(BULE);
}
if(cmd[3]==0x57)
{
f=cmd[12];
if(f>'9')
{
f=f-'A'+10;
}
else
{
f=f-'0';
}
w=f*16;
f=cmd[13];
if(f>'9')
{
f=f-'A'+10;
}
else
{
f=f-'0';
}
w=w+f;
LED_OFF(BULE);
printf("w=%d \r\n",w);
LED_ON(BULE);
}
}
}
}
经程序的编译和下载,其测试结果如图4和图5所示。其中图4是接收温度设置指令后的结果,可见开发板已接收到设置的温度值200;图5则是接收到读取温度指令后,所反馈回来的温度值100,说明程序处理正常。
图4 反馈测试1
图5 反馈测试2
在此基础上,所添加的变频器启停指令处理程序如下:
while(1)
{
if(zl==0x3A) // 变频器
{
i=0;
f=1;
while(f)
{
if (0x01UL == FL_UART_IsActiveFlag_RXBuffFull(UART4))
{
zl = (uint8_t)FL_UART_ReadRXBuff(UART4);
cmd[i]=zl;
i=i+1;
}
if(zl==0x0A)
{
f=0;
}
}
if(cmd[5]==0x04)
{
LED_OFF(BULE);
LED_ON(RED);
printf("RUN \r\n");
LED_ONBULE);
}
if(cmd[5]==0x02)
{
LED_OFF(RED);
LED_OFF(BULE);
printf("STOP \r\n");
LED_ONBULE);
}
}
}
该程序的测试结果如图6至图8所示,其中图7是模拟接收到启动指令后点亮红色指示灯,而图8则是接收到停止指令后关闭指示灯。
图6 启停指令测试
图7 模拟运行状态
图8 模拟停止状态
这里可能会引人发问,不是关闭指示灯吗,怎么蓝色指示灯还点亮?
这就引出了关于RS485通讯的问题,与常规的点多点串行通讯不同,RS485串行通讯是采用一对多的主从式通讯。在通讯过程中,是由主机控制着收发处理的节奏,属于主机发问从机应答的工作方式。
关于详细的RS485协议通讯过程,后面再继续介绍。
-
发表了主题帖:
【MCXA156开发板测评】+ 步进电机驱动与旋转LED灯
本帖最后由 jinglixixi 于 2025-2-9 16:53 编辑
原计划只是实现一个步进电机驱动控制,恰好赶上有一个春节点灯秀的活动,于是就将原内容同点灯秀结合起来搞。
由于电机在转动时,是较难传送电能,它会将传送电能的缠绕起来。此时,以感应的方式就能较好地解决这个问题,它可以使电能的发送与接收方隔离起来。当然,两者的间距还是有要求的,间距不能太大,否则就传送失效了。
以无线发送传送电能的测试效果如图1所示。
图1 以无线传送供电
由于发送端的线圈是圆形的,故步进电机的轴可以穿过发送线圈来托起随电机一起转动的接收线圈及电压控制电路等,实现无线供电且LED随电机一起转动的效果。
下面是步进电机的驱动控制,该步进电机与开发板的连接关系为:
A ---P3.12
B ---P3.13
C ---P3.15
D ---P3.16
对输出驱动电平的定义语句为:
#define MA_L GPIO_PinWrite(GPIO3, 1U << 12U, 0)
#define MA_H GPIO_PinWrite(GPIO3, 1U << 12U, 1)
#define MB_L GPIO_PinWrite(GPIO3, 1U << 13U, 0)
#define MB_H GPIO_PinWrite(GPIO3, 1U << 13U, 1)
#define MC_L GPIO_PinWrite(GPIO3, 1U << 15U, 0)
#define MC_H GPIO_PinWrite(GPIO3, 1U << 15U, 1)
#define MD_L GPIO_PinWrite(GPIO3, 1U << 16U, 0)
#define MD_H GPIO_PinWrite(GPIO3, 1U << 16U, 1)
对所用引脚的功能配置函数为:
void BJDJ_config(void)
{
gpio_pin_config_t led_config = {
kGPIO_DigitalOutput,
0,
};
CLOCK_EnableClock(kCLOCK_GateGPIO3);
GPIO_PinInit(GPIO3, 12U, &led_config);
GPIO_PinInit(GPIO3, 13U, &led_config);
GPIO_PinInit(GPIO3, 15U, &led_config);
GPIO_PinInit(GPIO3, 16U, &led_config);
}
电机旋的驱动旋转函数为:
void rotate(uint32_t n)
{
unsigned char a,b;
for(b=0;b<64;b++)
{
for(a=0;a<8;a++)
{
MD_L;
MA_H;
delay(n);
MB_H;
delay(n);
MA_L;
delay(n);
MC_H;
delay(n);
MB_L;
delay(n);
MD_H;
delay(n);
MC_L;
delay(n);
MA_H;
delay(n);
}
}
}
实现电机驱动控制的主程序为:
int main(void)
{
uint8_t m,i;
RESET_ReleasePeripheralReset(kLPUART0_RST_SHIFT_RSTn);
RESET_ReleasePeripheralReset(kPORT0_RST_SHIFT_RSTn);
RESET_ReleasePeripheralReset(kPORT1_RST_SHIFT_RSTn);
RESET_ReleasePeripheralReset(kGPIO1_RST_SHIFT_RSTn);
BOARD_InitPins();
BOARD_InitBootClocks();
BOARD_InitDebugConsole();
BJDJ_config();
MA_L;
MB_L;
MC_L;
MD_L;
Delay(5);
m=5;
for(i=0;i<m;i++)
{
rotate(2);
}
while(1);
}
经程序的编译与下载,其测试效果如图2所示。
图2 旋转的LED灯
测试视频:
[localvideo]6c79aae169ed95c48171973404a21222[/localvideo]
-
回复了主题帖:
【MCXA156开发板测评】点阵模块显示驱动
秦天qintian0303 发表于 2025-2-9 10:17
点阵驱动使用的芯片还是GPIO直驱?
驱动芯片是MAX7219
- 2025-02-08
-
回复了主题帖:
【新年花灯】方寸之间点阵模块也能庆新年
jobszheng5 发表于 2025-2-8 09:14
8x8的小LED点阵还真挺好玩的
的确挺有意思
- 2025-02-07
-
发表了主题帖:
【新年花灯】方寸之间点阵模块也能庆新年
本帖最后由 jinglixixi 于 2025-2-9 12:25 编辑
[localvideo]fef45831e9f6f154a707e4e861b05df8[/localvideo]
方寸之间庆新年
时间就在沙沙作响间
实现方法参见:
https://bbs.eeworld.com.cn/thread-1305820-1-1.html
[localvideo]67c5bfb70bfe2a6780bcf3e336db0756[/localvideo]
[localvideo]3e82be1b1d1413b1f9a6e3474569a3e5[/localvideo]
无线传能点亮LED灯
实现方法参见:
https://bbs.eeworld.com.cn/thread-1305927-1-1.html
-
发表了主题帖:
【MCXA156开发板测评】点阵模块显示驱动
本帖最后由 jinglixixi 于 2025-2-9 16:49 编辑
点阵显示模块具有显示字体大,可视范围远的特点,适于在公共场合使用,通常的点阵显示板是靠多个显示模块拼接而成。
这里就选取它的最小单元来进行驱动测试,该点阵模块的控制芯片是MAX7219。
该点阵模块的外观如图1所示,它采用串行的方式来传递数据,因此适于级联式的使用。
适逢新年,又有【新年花灯】的展示活动,就用这小小的点阵模块在方寸之间来庆祝新年吧!
图1点阵模块
驱动该显示模块的引脚为:
DIN---P3.14
CLK---P3.15
CS ---P3.13
输出高低电平所做的定义有:
#define CLK_SetLow GPIO_PinWrite(GPIO2,1U << 15U,0)
#define CLK_SetHigh GPIO_PinWrite(GPIO2,1U << 15U,1)
#define DIN_SetLow GPIO_PinWrite(GPIO3,1U << 14U,0)
#define DIN_SetHigh GPIO_PinWrite(GPIO3,1U << 14U,1)
#define CS_SetLow GPIO_PinWrite(GPIO3,1U << 13U,0)
#define CS_SetHigh GPIO_PinWrite(GPIO3,1U << 13U,1)
为发送字节数据所定义的函数为:
void Write_Max7219_byte(char DATA)
{
char i;
CS_SetLow;
delay(10);
for(i=8;i>=1;i--)
{
CLK_SetLow;
if(DATA&0x80)
DIN_SetHigh;
else
DIN_SetLow;
delay(10);
DATA=(char)(DATA<<1);
CLK_SetHigh;
delay(10);
}
}
发送指令的功能函数为:
void Write_Max7219(char address,char dat)
{
CS_SetLow;
Write_Max7219_byte(address);
Write_Max7219_byte(dat);
CS_SetHigh;
}
该点阵模块的初始化函数为:
void Init_MAX7219(void)
{
Write_Max7219(0x0b, 0x07);
Write_Max7219(0x0c, 0x01);
Write_Max7219(0x0f, 0x00);
}
由于点阵模块在显示时,是需要字模支持的,为其配置相应的字模数组为:
unsigned char disp[39][8]={
{0x3C,0x42,0x42,0x42,0x42,0x42,0x42,0x3C},//0
{0x10,0x18,0x14,0x10,0x10,0x10,0x10,0x10},//1
{0x7E,0x2,0x2,0x7E,0x40,0x40,0x40,0x7E},//2
{0x3E,0x2,0x2,0x3E,0x2,0x2,0x3E,0x0},//3
{0x8,0x18,0x28,0x48,0xFE,0x8,0x8,0x8},//4
{0x3C,0x20,0x20,0x3C,0x4,0x4,0x3C,0x0},//5
{0x3C,0x20,0x20,0x3C,0x24,0x24,0x3C,0x0},//6
{0x3E,0x22,0x4,0x8,0x8,0x8,0x8,0x8},//7
{0x0,0x3E,0x22,0x22,0x3E,0x22,0x22,0x3E},//8
{0x3E,0x22,0x22,0x3E,0x2,0x2,0x2,0x3E},//9
{0x8,0x14,0x22,0x3E,0x22,0x22,0x22,0x22},//A 10
{0x3C,0x22,0x22,0x3E,0x22,0x22,0x3C,0x0},//B
{0x3C,0x40,0x40,0x40,0x40,0x40,0x3C,0x0},//C
{0x7C,0x42,0x42,0x42,0x42,0x42,0x7C,0x0},//D
{0x7C,0x40,0x40,0x7C,0x40,0x40,0x40,0x7C},//E
{0x7C,0x40,0x40,0x7C,0x40,0x40,0x40,0x40},//F 15
{0x3C,0x40,0x40,0x40,0x40,0x44,0x44,0x3C},//G
{0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x44},//H
{0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x7C},//I
{0x3C,0x8,0x8,0x8,0x8,0x8,0x48,0x30},//J
{0x0,0x24,0x28,0x30,0x20,0x30,0x28,0x24},//K 20
{0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7C},//L
{0x81,0xC3,0xA5,0x99,0x81,0x81,0x81,0x81},//M
{0x0,0x42,0x62,0x52,0x4A,0x46,0x42,0x0},//N
{0x3C,0x42,0x42,0x42,0x42,0x42,0x42,0x3C},//O
{0x3C,0x22,0x22,0x22,0x3C,0x20,0x20,0x20},//P 25
{0x1C,0x22,0x22,0x22,0x22,0x26,0x22,0x1D},//Q
{0x3C,0x22,0x22,0x22,0x3C,0x24,0x22,0x21},//R
{0x0,0x1E,0x20,0x20,0x3E,0x2,0x2,0x3C},//S
{0x0,0x3E,0x8,0x8,0x8,0x8,0x8,0x8},//T
{0x42,0x42,0x42,0x42,0x42,0x42,0x22,0x1C},//U 30
{0x42,0x42,0x42,0x42,0x42,0x42,0x24,0x18},//V
{0x0,0x49,0x49,0x49,0x49,0x2A,0x1C,0x0},//W
{0x0,0x41,0x22,0x14,0x8,0x14,0x22,0x41},//X
{0x41,0x22,0x14,0x8,0x8,0x8,0x8,0x8},//Y
{0x0,0x7F,0x2,0x4,0x8,0x10,0x20,0x7F},//Z 35
{0x8,0x7F,0x49,0x49,0x7F,0x8,0x8,0x8},
{0xFE,0xBA,0x92,0xBA,0x92,0x9A,0xBA,0xFE},
{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
};
显示“HAPPY NEW YEAR”的测试主程序为:
int main(void)
{
uint8_t i,n,f,m,j;
uint16_t k;
gpio_pin_config_t led_config = {
kGPIO_DigitalOutput,
0,
};
CLOCK_SetClkDiv(kCLOCK_DivFlexcom4Clk, 1u);
CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);
CLOCK_EnableClock(kCLOCK_Gpio0);
CLOCK_EnableClock(kCLOCK_Gpio1);
CLOCK_EnableClock(kCLOCK_Gpio3);
BOARD_InitPins();
BOARD_InitBootClocks();
BOARD_InitDebugConsole();
GPIO_PinInit(GPIO3, 13U, &led_config);
GPIO_PinInit(GPIO3, 14U, &led_config);
GPIO_PinInit(GPIO3, 15U, &led_config);
Init_MAX7219();
while(1)
{
for(j=0;j<14;j++)
{
n=ch[j];
for(i=1;i<9;i++)
{
Write_Max7219(i,disp[n][i-1]);
for(k=1;k<200;k++)
{
delay_n(20);
}
}
for(k=1;k<400;k++)
{
delay_n(500);
}
}
}
}
经程序的编译和下载,其显示效果如图2和视频所示。
图2 显示效果
视频展示:
[localvideo]d874310cb793053b09fca741b50308cb[/localvideo]
在沙漏的显示效果中,有种跳棋的感觉,这次就在点阵模块完成一个平滑的变化效果。
记得学习数据结构时,有次讲到荷兰旗问题,讲课的老师说好的算法可以写下来贴到床头欣赏。
这次在写这个平滑处理的程序时,就找到了些许的感觉,在此与大家分享。
实现沙漏变化效果的主程序为:
int main(void)
{
uint8_t i,n,f,m,j;
uint16_t k;
gpio_pin_config_t led_config = {
kGPIO_DigitalOutput,
0,
};
CLOCK_SetClkDiv(kCLOCK_DivFlexcom4Clk, 1u);
CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);
CLOCK_EnableClock(kCLOCK_Gpio0);
CLOCK_EnableClock(kCLOCK_Gpio1);
CLOCK_EnableClock(kCLOCK_Gpio3);
BOARD_InitPins();
BOARD_InitBootClocks();
BOARD_InitDebugConsole();
GPIO_PinInit(GPIO3, 13U, &led_config);
GPIO_PinInit(GPIO3, 14U, &led_config);
GPIO_PinInit(GPIO3, 15U, &led_config);
Init_MAX7219();
while(1)
{
d=0x01;
for(j=0;j<16;j++)
{
a=d;
for(k=0;k<=j;k++)
{
b=m[k%8];
m[k%8]=m[k%8]|a;
a=b;
}
d=d<<1;
for(i=1;i<9;i++)
{
Write_Max7219(i,m[i-1]);
for(k=1;k<200;k++)
{
delay_n(20);
}
}
for(k=1;k<100;k++)
{
delay_n(500);
}
}
d=0xfe;
for(j=0;j<16;j++)
{
a=d;
for(k=0;k<=j;k++)
{
b=m[k%8];
m[k%8]=m[k%8]&a;
a=b;
}
d=d<<1;
for(i=1;i<9;i++)
{
Write_Max7219(i,m[i-1]);
for(k=1;k<200;k++)
{
delay_n(20);
}
}
for(k=1;k<100;k++)
{
delay_n(500);
}
}
}
}
经程序的编译与下载,其显示效果图3和视频所示。
图3 显示效果
视频展示:
[localvideo]78f1be2163a2af5b87af24868758b2d4[/localvideo]
- 2025-02-06
-
发表了主题帖:
【泰坦触觉 TITAN Core开发套件】触觉感知控制器的实现
对于听障人群来说,在特定的环境下,听力的缺失是致命。为了弥补和降低这方面的损失,触觉感知控制器的作用是不可或缺的。
该触觉感知控制器要解决的问题是,通过相应的传感器感知周围的危险并其以触觉感知的方式传递给他们。
此外,是将健听人群所感知的情况,通过按键的触发以固定的触觉方式通知给他们。
归结到硬件设计上就是以ETEB-6001DPX-V1开发板为控制中心,通过4个A/D检测通道来采集火焰、易燃气体、热释及土壤湿度传感器的输出信号,并以触发触觉马达输出报警提示。另外就是指定4个有特定等级含义的触摸键,通过人为的触发使触觉马达发出提示信号,以及时呼唤他们尽快搜寻周围环境的变化或了解触摸信号的含义。
另外,为指示相应的通知信号已发出,还配置了对应的TFT显示屏,并红色的方框来标识出是何种情况下触发的触觉提示。
为显示汉字,所配备的显示函数为:
汉字显示函数:
void showhanzi16h(unsigned int x,unsigned int y,unsigned char index,unsigned char s)
{
unsigned char i,j,k;
const unsigned char *temp=hanzi16;
temp+=index*32;
for(j=0;j<16;j++)
{
for(k=0;k<2;k++)
{
for(i=0;i<8;i++)
{
if((*temp&(1<<i))!=0)
{
POINT_COLOR=WHITE;
}
else
{
POINT_COLOR=RED;
}
LCD_DrawPoint(x+j,y-k*8-i);
}
temp++;
}
}
}
实现图标显示的函数为:
void show_tbh(unsigned int x,unsigned int y,unsigned int n)
{
unsigned int i,j,k;
unsigned int da;
k=0;
for(i=0;i<50;i++)
{
for(j=0;j<50;j++)
{
if(n==0) da=gImage_t1[k*2];
if(n==1) da=gImage_t2[k*2];
if(n==2) da=gImage_t3[k*2];
if(n==3) da=gImage_t4[k*2];
if(n==4) da=gImage_t5[k*2];
if(n==5) da=gImage_t6[k*2];
if(n==6) da=gImage_t7[k*2];
if(n==7) da=gImage_t8[k*2];
da<<=8;
if(n==0) da|=gImage_t1[k*2+1];
if(n==1) da|=gImage_t2[k*2+1];
if(n==2) da|=gImage_t3[k*2+1];
if(n==3) da|=gImage_t4[k*2+1];
if(n==4) da|=gImage_t5[k*2+1];
if(n==5) da|=gImage_t6[k*2+1];
if(n==6) da|=gImage_t7[k*2+1];
if(n==7) da|=gImage_t8[k*2+1];
POINT_COLOR=da;
LCD_DrawPoint(x+i,y+j);
k++;
}
}
}
实现界面显示效果的函数为:
void jm(void)
{
LCD_Clear(RED);
show_tbh(45,20,7);
show_tbh(45,97,0);
show_tbh(45,174,5);
show_tbh(45,250,6);
show_tbh(145,20,1);
show_tbh(145,97,2);
show_tbh(145,174,4);
show_tbh(145,250,3);
POINT_COLOR=YELLOW;
LCD_DrawLine(32, 0, 32, 319);
BACK_COLOR=RED;
POINT_COLOR=WHITE;
LCD_ShowStringh(10,80," 8:30:00");
showhanzi16h(10,240,0,0);
showhanzi16h(10,220,1,0);
showhanzi16h(10,200,2,0);
showhanzi16h(10,180,3,0);
showhanzi16h(10,160,4,0);
showhanzi16h(10,140,5,0);
showhanzi16h(10,120,6,0);
showhanzi16h(110,295,7,0);
showhanzi16h(110,275,8,0);
showhanzi16h(110,220,9,0);
showhanzi16h(110,200,10,0);
showhanzi16h(110,142,11,0);
showhanzi16h(110,122,12,0);
showhanzi16h(110,67,13,0);
showhanzi16h(110,47,14,0);
showhanzi16h(210,295,15,0);
showhanzi16h(210,275,16,0);
showhanzi16h(210,220,17,0);
showhanzi16h(210,200,18,0);
showhanzi16h(210,142,19,0);
showhanzi16h(210,122,17,0);
showhanzi16h(210,67,20,0);
showhanzi16h(210,47,19,0);
}
图1 图标显示效果
为按键所用引脚的配置函数为:
static void KEY_Init(void)
{
IOC_Init_TypeDef init;
IOC_ConfigStructInit(&init);
init.mode = IOC_AF_MODE_0;
init.dir = GPIO_DIR_IN_OUT;
init.pull = IOC_PULL_NONE;
IOC_Config(IOC_PIN_GPIO_PLL_REF, &init);
GPIO_PortOutputDisable(GPIO0, GPIO_PIN_11);
GPIO_PortOutputDisable(GPIO0, GPIO_PIN_12);
GPIO_PortOutputDisable(GPIO0, GPIO_PIN_13);
GPIO_PortOutputDisable(GPIO0, GPIO_PIN_15);
}
图2 连接触摸式按键
进行功能测试的主程序为:
int main(void)
{
EVB_LEDInit();
tft_Init();
LCD_Clear(RED);
LCD_Clear(RED);
show_tbh(45,20,7);
show_tbh(45,97,0);
show_tbh(45,174,5);
show_tbh(45,250,6);
show_tbh(145,20,1);
show_tbh(145,97,2);
show_tbh(145,174,4);
show_tbh(145,250,3);
POINT_COLOR=YELLOW;
LCD_DrawLine(32, 0, 32, 319);
BACK_COLOR=RED;
POINT_COLOR=WHITE;
LCD_ShowStringh(10,80," 8:30:00");
showhanzi16h(10,240,0,0);
showhanzi16h(10,220,1,0);
showhanzi16h(10,200,2,0);
showhanzi16h(10,180,3,0);
showhanzi16h(10,160,4,0);
showhanzi16h(10,140,5,0);
showhanzi16h(10,120,6,0);
showhanzi16h(110,295,7,0);
showhanzi16h(110,275,8,0);
showhanzi16h(110,220,9,0);
showhanzi16h(110,200,10,0);
showhanzi16h(110,142,11,0);
showhanzi16h(110,122,12,0);
showhanzi16h(110,67,13,0);
showhanzi16h(110,47,14,0);
showhanzi16h(210,295,15,0);
showhanzi16h(210,275,16,0);
showhanzi16h(210,220,17,0);
showhanzi16h(210,200,18,0);
showhanzi16h(210,142,19,0);
showhanzi16h(210,122,17,0);
showhanzi16h(210,67,20,0);
showhanzi16h(210,47,19,0);
SW_Init();
GPIO_WritePin(GPIO2, GPIO_PIN_00, RESET);
while (1)
{
if(GPIO_ReadPin(GPIO0, GPIO_PIN_12)==SET)
{
showhanzi16h(210,295,15,1);
showhanzi16h(210,275,16,1);
GPIO_WritePin(GPIO2, GPIO_PIN_00, RESET);
}
else
{
showhanzi16h(210,295,15,0);
showhanzi16h(210,275,16,0);
GPIO_WritePin(GPIO2, GPIO_PIN_00,SET);
}
if(GPIO_ReadPin(GPIO0, GPIO_PIN_11)==SET)
{
showhanzi16h(210,220,17,1);
showhanzi16h(210,200,18,1);
}
else
{
showhanzi16h(210,220,17,0);
showhanzi16h(210,200,18,0);
}
if(GPIO_ReadPin(GPIO0, GPIO_PIN_15)==SET)
{
showhanzi16h(210,142,19,1);
showhanzi16h(210,122,17,1);
}
else
{
showhanzi16h(210,142,19,0);
showhanzi16h(210,122,17,0);
}
if(GPIO_ReadPin(GPIO0, GPIO_PIN_13)==SET)
{
showhanzi16h(210,67,20,1);
showhanzi16h(210,47,19,1);
}
else
{
showhanzi16h(210,67,20,0);
showhanzi16h(210,47,19,0);
}
delay_1us(20);
}
}
经程序的编译和运行,其测试效果如图3所示,说明程序符合预期效果。
图3 危险提示状态
-
发表了主题帖:
【复旦微车规MCU FM32FT0A测评】仪表数据读取(1)
本帖最后由 jinglixixi 于 2025-2-9 16:59 编辑
在常规的流变分析仪设计中,离不开以下设备和仪表的使用:
1)变频器
通过变频器来控制伺服电机的启停及转速的设置
2)温度控制仪
通过温度控制仪来控制加热棒以使高分子聚合物处于融和状态
3)应变器
各种应变器是用来检测高分子聚合物在相应的温度下,它的温度、压力、扭矩及转速等参数,以配置不同性能的产品。
由于流变仪控制的对象及检测的参数比较多,单凭常规的串行通讯是难以解决问题的,为此在多数情况下是采用基于RS485的多设备协议通讯。
为了简化设计,对温度、压力及扭矩的检测,多是采用相应的应变器来获得4~20mA的电流信号,再通过变换器件将其转化为0~5V的电压信号,进而通过多通道的A/D转换器转化为数字信号以供分析处理和波形绘制。而对于转速信号及部分的扭矩信号,则是通过在定位时间内的脉冲信号捕捉和计数来获得。
这样,RS485协议通讯的主体就只落在变频器和温度控制仪的身上。
变频器及相关指令:
这里选用的变频器型号是S1100,其控制启停指令如下:
使电机启动的指令为:
:01 06 2000 0004 D5 OD 0A
其校验码=D5,即:01H+06H+20H+00H+00H+04H=2BH,2BH取反+1=D5H。
使电机停止的指令为:
:01 06 2000 0002 D7 OD 0A
其校验码=D7,即:01H+06H+20H+00H+00H+02H=29H,29H取反+1=D7H。
温度控制仪及相关指令:
为保证控制温度的质量,这里选用的是岛电公司出产的MR13温度调节器,其读写温度的指令如下:
设置温度
以设置温度为200(0xC8)度为例,其指令为:
@021W04000,00C8:EACRLF
读取温度
以读取地址400H的温度为例,其指令为:
@021R04000:DECR LF
在读取温度时,除了发出读取指令,还要接收和提取数据值。
设接收到返回信息为:@021R00,0064:40 CR LF
则其检测的温度值为:0064H=100度。
后续再介绍指令的发送及其相应的处理,这里先作一下铺垫。
-
回复了主题帖:
【新年花灯】莫负时光砥砺前行
秦天qintian0303 发表于 2025-2-6 08:49
简化才不容易呢
哈哈,主要是参与活动凑个热闹。
-
回复了主题帖:
【新年花灯】莫负时光砥砺前行
秦天qintian0303 发表于 2025-2-5 21:11
第一个有点像跳棋,不过看着效果都不错
主要是为了简化程序有些粗糙
- 2025-02-05
-
回复了主题帖:
【新年花灯】莫负时光砥砺前行
rto 发表于 2025-2-5 17:06
很有创意,花灯也漂亮,电子人的新年过的真好。希望楼主多发点类似主题。
好的,继续努力。
-
回复了主题帖:
【新年花灯】莫负时光砥砺前行
se7ens 发表于 2025-2-5 17:01
很有创意,LED沙漏和LED时钟,都是用51做的吗
沙漏用的芯片是STC2051,旋转时钟用的STC8052。
- 2025-02-04
-
回复了主题帖:
【复旦微车规MCU FM32FT0A测评】触摸功能检测
哈哈,为了能直观地观察其触摸后的变化情况,于是为它配了串口输出来显示状态信息。
- 2025-02-03
-
发表了主题帖:
【复旦微车规MCU FM32FT0A测评】语音提示功能的实现
流变分析器的工作过程中,涉及接触高温和物体缠绕的物体,为防止意外的出现,适时地发出语音提示是十分必要的安全措施之一。
将串口与MP3语音模块相结合,在适当的时机触发语音播报即可实现这样要求。
MP3语音模块及其引脚排列如图1所示,在一般情况下,它只需与开发板连接3条线,即5V电源、GND及串口发送信号端,这里是连接UART4_TX即引脚PB3。
图1 模块引脚排列
MP3语音模块工作的波特率为9600bps,为便于其控制指令是存放在数组中,即:
uint8_t cmd3[] = {0X7E, 0xFF, 0x06, 0X03, 00, 00, 01, 0xFE, 0xF7, 0XEF};
实现指定提示内容的指令生成函数为:
void playn(uint16_t index)
{
int i;
uint8_t checksum = 0;
cmd3[5] = (uint8_t)(index >> 8);
cmd3[6] = (uint8_t)(index);
for (i=2; i<8; i++)
{
checksum += cmd3[i];
}
cmd3[8] = (uint8_t)~checksum;
}
基于感应触发的语音提示功能测试主程序为:
int main(void)
{
uint8_t f,p,i;
IWDT_Init(FL_IWDT_PERIOD_4000MS);
FL_Init();
SVD_Init(SVD_MONTIOR_VDD, FL_SVD_WARNING_THRESHOLD_GROUP11, FL_SVD_REFERENCE_1P0V);
while(false == SVD_Result_Confirmed(SVD_HIGHER_THRESHOLD, 2000U/*us*/));
RMU_BOR_Init(FL_RMU_BOR_THRESHOLD_2P00V);
SystemClockInit();
MF_UART4_Init();
TSI_Init();
FL_IWDT_ReloadCounter(IWDT);
TSI_Widget_EnableAll();
FL_IWDT_ReloadCounter(IWDT);
TSI_Start();
FL_IWDT_ReloadCounter(IWDT);
f=0;
p=0;
while(1)
{
FL_IWDT_ReloadCounter(IWDT);
PowerDownMonitoring();
TSI_Debug_Handler();
FL_IWDT_ReloadCounter(IWDT);
if(TSI_GETSTAT_SCAN_CPLT())
{
TSI_CLRSTAT_SCAN_CPLT();
TSI_Widget_UpdateAll();
if(TSI_WidgetList.slider.sliderStatus==1)
{
f=TSI_WidgetList.slider.centerPos/50;
if(f!=p)
{
printf("N= %d\n\r",f);
playn(f);
for(i=0;i<10;i++)
{
FL_UART_WriteTXBuff(UART4, cmd3[i]);
while(FL_UART_IsActiveFlag_TXBuffEmpty(UART4) != 0x01UL);
}
p=f;
}
}
}
}
}
经程序的编译与下载,其测试效果如图2和图3所示,说明设计功能正确。
图2 触发值测试
图3 提示指令测试