X
首页
技术
模拟电子
单片机
半导体
电源管理
嵌入式
传感器
最能打国产芯
应用
汽车电子
工业控制
家用电子
手机便携
安防电子
医疗电子
网络通信
测试测量
物联网
最能打国产芯
大学堂
首页
直播
专题
TI 培训
论坛
汽车电子
国产芯片
电机驱动控制
电源技术
单片机
模拟电子
PCB设计
电子竞赛
DIY/开源
嵌入式系统
医疗电子
颁奖专区
【厂商专区】
【电子技术】
【创意与实践】
【行业应用】
【休息一下】
最能打国产芯
活动中心
直播
发现活动
颁奖区
电子头条
参考设计
下载中心
分类资源
文集
排行榜
电路图
Datasheet
最能打国产芯
国产芯片交流
[MCU] 【AT-START-F425测评】No.06 驱动段码LCD
韵湖葱白
2022-5-10 18:43
楼主
## 前言 还是之前折腾GD32L233时弄的一块SLCD屏,改吧改吧就在AT32F425上跑起来了。 板子其实比较简单,打板如下: ![SLCD板](https://s2.loli.net/2022/04/29/HxmlgykbJecN7P6.jpg) 其中: 信号管脚RC参数中的R参数以及VLCD的分压电阻可直接参考手册。 ## 如何测试裸屏 裸屏是交流信号驱动,直接用DC是不行的,得用交流测试。 用一段线缠绕在交流线上面,就可以测试了。 ![SLCD裸屏测试](https://s2.loli.net/2022/05/10/C4mtpsQLWK28OIP.jpg) ![测试结果](https://s2.loli.net/2022/05/10/EFCKSTOeohmJVQp.gif) ## 段码液晶的原理 ![SLCD参数](https://s2.loli.net/2022/04/29/D3SCYnfdzHgcbV2.jpg) 其中最关键的驱动条件参数,一般而言: - duty = 1/com的数量 - bias = 1/(sqrt(duty)+1) ![SLCD COM和SEG](https://s2.loli.net/2022/04/29/iTLJMCdQWXFr8R9.jpg) SLCD按duty的周期执行扫描模式,所以简单的理解: - SEG = 地址 - COM = 数据 --- 假如我们需要显示第一位的数字为2,那么对应的【8】,其中:标号2,标号3,标号4,标号6,标号7会亮。 参考SEG图,我们知道: - SEG 9对应的是标号1,标号2,标号3,标号4共4段。 - SEG 10对应的是标号5,标号6,标号7共3段(电池图标我们不用)。 要想把标号2,标号3,标号4,标号6,标号7点亮,那么: - SEG 9:COM0(标号4),COM1(标号3),COM2(标号2)为1。 - SEG 10:COM2(标号3),COM3(标号2)为1。 就是下表: || COM0 | COM1 | COM2 | COM3 | | --- | --- | --- | --- | --- | | SEG9 | 1 | 1 | 1 | 0 | | SEG10 | 0 | 0 | 1 | 1 | 也就是往这两个地址写入0xE和0x3就能显示数字2。 懂了啵?! ## AT32的GPIO口 只说跟STM32、GD32的差异性吧。 ### GPIO的驱动能力 是定义了2个宏定义。 ``` GPIO_DRIVE_STRENGTH_STRONGER = 0x01, /*!< stronger sourcing/sinking strength */ GPIO_DRIVE_STRENGTH_MODERATE = 0x02/*!< moderate sourcing/sinking strength */ ``` ### GPIO的复用 又单独给每个管脚定义了SOURCE,封装起来又多了一个函数。 GPIO的封装接口: ``` static gpio_pins_source_type get_gpio_pins_source(uint32_t pin) { switch (pin) { case GPIO_PINS_0: return GPIO_PINS_SOURCE0; case GPIO_PINS_1: return GPIO_PINS_SOURCE1; case GPIO_PINS_2: return GPIO_PINS_SOURCE2; case GPIO_PINS_3: return GPIO_PINS_SOURCE3; case GPIO_PINS_4: return GPIO_PINS_SOURCE4; case GPIO_PINS_5: return GPIO_PINS_SOURCE5; case GPIO_PINS_6: return GPIO_PINS_SOURCE6; case GPIO_PINS_7: return GPIO_PINS_SOURCE7; case GPIO_PINS_8: return GPIO_PINS_SOURCE8; case GPIO_PINS_9: return GPIO_PINS_SOURCE9; case GPIO_PINS_10: return GPIO_PINS_SOURCE10; case GPIO_PINS_11: return GPIO_PINS_SOURCE11; case GPIO_PINS_12: return GPIO_PINS_SOURCE12; case GPIO_PINS_13: return GPIO_PINS_SOURCE13; case GPIO_PINS_14: return GPIO_PINS_SOURCE14; case GPIO_PINS_15: return GPIO_PINS_SOURCE15; default: return GPIO_PINS_SOURCE0; } } void gpio_init_af_mode(crm_periph_clock_type rcu, gpio_type * gpio, uint32_t pin, uint32_t speed, uint32_t af_func) { gpio_init_type gpio_init_struct; crm_periph_clock_enable(rcu, TRUE); gpio_default_para_init(&gpio_init_struct); gpio_init_struct.gpio_drive_strength = (gpio_drive_type)speed; gpio_init_struct.gpio_out_type= GPIO_OUTPUT_PUSH_PULL; gpio_init_struct.gpio_mode = GPIO_MODE_MUX; gpio_init_struct.gpio_pins = pin; gpio_init_struct.gpio_pull = GPIO_PULL_NONE; gpio_init(gpio, &gpio_init_struct); gpio_pin_mux_config(gpio, get_gpio_pins_source(pin), (gpio_mux_sel_type)af_func); } void gpio_init_output_mode(crm_periph_clock_type rcu, gpio_type * gpio, uint32_t pin, uint32_t speed, uint8_t set) { gpio_init_type gpio_init_struct; crm_periph_clock_enable(rcu, TRUE); gpio_default_para_init(&gpio_init_struct); gpio_init_struct.gpio_drive_strength = (gpio_drive_type)speed; gpio_init_struct.gpio_out_type= GPIO_OUTPUT_PUSH_PULL; gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT; gpio_init_struct.gpio_pins = pin; gpio_init_struct.gpio_pull = GPIO_PULL_NONE; gpio_init(gpio, &gpio_init_struct); if (set) { gpio_bits_set(gpio, pin); } else { gpio_bits_reset(gpio, pin); } } ``` ## 驱动代码 一堆寄存器配置,参见芯片手册。 偷个懒,一把贴出来了。 【说明】SLCD切换的时序很短,延时直接用计数--就好。 这个代码跟GD32L233的代码几乎一致,只是定义的管脚和接口宏定义变了,这就是架构提前设计好的好处。 ``` //#define SLCD_USING_SPI #if defined(SPI1_FOR_SLCD) /* SPI1:PB13-SCK-SPI_SCK PB14-CE-SPI_MISO PB15-DATA-SPI_MOSI */ #define CURRENT_SPI SPI1 #define CURRENT_SPI_RCU RCU_SPI1 #define SLCD_RCU CRM_GPIOB_PERIPH_CLOCK #define SLCD_GPIO GPIOB #define SLCD_WR_CLK_PINGPIO_PINS_13 #define SLCD_CS_PIN GPIO_PINS_14 #define SLCD_DATA_PIN GPIO_PINS_15 #ifdef SLCD_USING_SPI #else #define CS_HIGH gpio_bits_set(SLCD_GPIO, SLCD_CS_PIN); #define CS_LOW gpio_bits_reset(SLCD_GPIO, SLCD_CS_PIN); #define WR_CLK_HIGH gpio_bits_set(SLCD_GPIO, SLCD_WR_CLK_PIN); #define WR_CLK_LOWgpio_bits_reset(SLCD_GPIO, SLCD_WR_CLK_PIN); #define DATA_HIGH gpio_bits_set(SLCD_GPIO, SLCD_DATA_PIN); #define DATA_LOW gpio_bits_reset(SLCD_GPIO, SLCD_DATA_PIN); #define DATA gpio_input_data_bit_read(SLCD_GPIO, SLCD_DATA_PIN) #endif // SLCD命令码 #defineCTRL_CMD 0x80//写控制命令 #defineDATA_CMD 0xA0//写数据命令 #define LCD_ON 0x06//打开LCD 1000 0000 011x #define LCD_OFF 0x04//关闭LCD 1000 0000 010x #define SYS_EN 0x02//系统振荡器开 1000 0000 001x #define RC_OSC 0x30//内部RC振荡器(上电默认256K) 1000 0011 0XXX #define COM_BIAS 0x52//4COM,1/3bias 1000 010 10X1X #define SLCD_OFF send_cmd_slcd(LCD_OFF) #define SLCD_ON send_cmd_slcd(LCD_ON) #define SLCD_SYS_EN send_cmd_slcd(SYS_EN) #define SLCD_RC_OSC send_cmd_slcd(RC_OSC) #define SLCD_COM_BIAS send_cmd_slcd(COM_BIAS) //,C,c,d,E,F,H,h,L,n,N,o,P,r,t,U,-, ,*/ //,,0x1D,0x0E,0x6E,0x1F,0x17,0x67,0x47,0x0D,0x46,0x75,0x37, #define DISP_0 0xD7 #define DISP_1 0x06 #define DISP_2 0xE3 #define DISP_3 0xA7 #define DISP_4 0x36 #define DISP_5 0xB5 #define DISP_6 0xF5 #define DISP_7 0x07 #define DISP_8 0xF7 #define DISP_9 0xB7 #define DISP_A 0x77 #define DISP_B 0xF7 #define DISP_b 0xF4 #define DISP_C 0xD1 #define DISP_D 0xD7 #define DISP_c 0xE0 #define DISP_d 0xE6 #define DISP_E 0xF1 #define DISP_F 0x71 #define DISP_H 0x76 #define DISP_h 0x74 #define DISP_L 0xD0 #define DISP_n 0x64 #define DISP_N 0x57 #define DISP_o 0xE4 #define DISP_P 0x73 #define DISP_r 0x60 #define DISP_t 0xF0 #define DISP_U 0xD6 #define DISP__ 0x20 #define DISP_EMPTY0x00 void spi5_init(){} #ifdef SLCD_USING_SPI void spi1_init() { } #else void spi1_init() { gpio_init_output_mode(SLCD_RCU, SLCD_GPIO, SLCD_WR_CLK_PIN,GPIO_DRIVE_STRENGTH_MODERATE, 0); gpio_init_output_mode(SLCD_RCU, SLCD_GPIO, SLCD_CS_PIN,GPIO_DRIVE_STRENGTH_MODERATE, 0); gpio_init_output_mode(SLCD_RCU, SLCD_GPIO, SLCD_DATA_PIN,GPIO_DRIVE_STRENGTH_STRONGER, 0); } static void slcd_delay(int count) { while (count) { count--; } } void send_bit_slcd(uint8_t sdat, uint8_t cnt) { //data 的高cnt位写入,高位在前 uint8_t i; for(i = 0; i < cnt; i++) { WR_CLK_LOW; slcd_delay(20); if(sdat&0x80) { DATA_HIGH; } else { DATA_LOW; } slcd_delay(20); WR_CLK_HIGH; slcd_delay(20); sdat<<=1; } slcd_delay(20); } void send_cmd_slcd(uint8_t command) { //发送指令 CS_LOW; send_bit_slcd(CTRL_CMD, 4); //写入标志码b100 send_bit_slcd(command, 8); //没有最高位为1的命令,直接将command的最高位写0 CS_HIGH; } void write_slcd(uint8_t addr, uint8_t sdat) { addr<<=2; CS_LOW; send_bit_slcd(DATA_CMD, 3); //写入标志码b101 send_bit_slcd(addr, 6); //写入addr 的高6位 send_bit_slcd(sdat, 8); //写入data 的8位 CS_HIGH; } void slcd_user_init(void) { SLCD_OFF; SLCD_SYS_EN; SLCD_RC_OSC; SLCD_COM_BIAS; SLCD_ON; slcd_display_data(DISP_0,DISP_0,DISP_0,DISP_0,DISP_0,DISP_0);delay_ms(600); slcd_display_data(DISP_1,DISP_1,DISP_1,DISP_1,DISP_1,DISP_1);delay_ms(600); slcd_display_data(DISP_2,DISP_2,DISP_2,DISP_2,DISP_2,DISP_2);delay_ms(600); slcd_display_data(DISP_3,DISP_3,DISP_3,DISP_3,DISP_3,DISP_3);delay_ms(600); slcd_display_data(DISP_4,DISP_4,DISP_4,DISP_4,DISP_4,DISP_4);delay_ms(600); slcd_display_data(DISP_5,DISP_5,DISP_5,DISP_5,DISP_5,DISP_5);delay_ms(600); slcd_display_data(DISP_6,DISP_6,DISP_6,DISP_6,DISP_6,DISP_6);delay_ms(600); slcd_display_data(DISP_7,DISP_7,DISP_7,DISP_7,DISP_7,DISP_7);delay_ms(600); slcd_display_data(DISP_8,DISP_8,DISP_8,DISP_8,DISP_8,DISP_8);delay_ms(600); slcd_display_data(DISP_9,DISP_9,DISP_9,DISP_9,DISP_9,DISP_9);delay_ms(600); slcd_display_data(DISP__,DISP__,DISP__,DISP__,DISP__,DISP__);delay_ms(600); slcd_display_data(DISP_H,DISP_E,DISP_L,DISP_L,DISP_0,DISP_EMPTY); } void slcd_display_data(uint8_t data1, uint8_t data2, uint8_t data3, uint8_t data4, uint8_t data5, uint8_t data6) { uint8_t addr = 9; write_slcd(addr, data1); addr += 2; write_slcd(addr, data2); addr += 2; write_slcd(addr, data3); addr += 2; write_slcd(addr, data4); addr += 2; write_slcd(addr, data5); addr += 2; write_slcd(addr, data6); addr += 2; } #endif #endif ``` ## 视频 ![](https://s2.loli.net/2022/05/10/kxR7XlJSdHLmV2g.gif) ![](https://s2.loli.net/2022/03/28/xnJPMjvEfwHs1IS.gif)
点赞
回复评论 (1)
沙发
lugl4313820
有空测测这段码评的功耗如何呀。
点赞
2022-5-10 21:56
最新活动
报名直播赢【双肩包、京东卡、水杯】| 高可靠性IGBT的新选择——安世半导体650V IGBT
30套RV1106 Linux开发板(带摄像头),邀您动手挑战边缘AI~
安世半导体理想二极管与负载开关,保障物联网应用的稳健高效运行
免费申请 | 上百份MPS MIE模块,免费试用还有礼!
PI 电源小课堂|无 DC-DC 变换实现多路高精度输出反激电源
2024 瑞萨电子MCU/MPU工业技术研讨会——深圳、上海站, 火热报名中
随便看看
CCS导入工程及编译下载
zstack 路由和终端共用一套程序,能否实现?
晒晒俺的 中国版BeagleBone-Black
求推荐信誉好实惠的PCB制版厂家
测速模块老不好
LESSON3_加速度传感器简单玩起来
感光太阳能实时对焦及最合理利用光源
饭前从老板手里拿到3张“好玩的卡片”
ccs3.3 无法保存添加的文件
中频PCM/DPSK解调器中滤波器的设计
嵌入式课程体系最佳设计
新人求助。。。关于二阶高通有源滤波
luninary驱动库中CAN问题!
EVC+OLEDB编译报错,急人啊
MSP430 选型
急急求:数据库文件和备份文件无法复制,数据错误,(循环冗余检查)
求一款闲置的STM32F429-DISCO开发板
这是两个不同的电源,请问能采集到R0的压降不?得到电压的AD值,除以电阻值,从而...
为什么我们不要 .NET 程序员
目前有个棘手的问题,usb有时候连不上
电子工程世界版权所有
京B2-20211791
京ICP备10001474号-1
京公网安备 11010802033920号
回复
写回复
收藏
回复