完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
一、探索
这是一个从乐心血压计上拆下来的屏幕,有40个引脚,其中1和40、2和39、3和38、4和37在PCB上是连起来的,所以实际上是36个引脚。 在其引脚上加电压,得到的不是数码管的效果。 COM和COM之间加电压 COM和SEG之间加电压 查询了一番之后方得知这种屏是段码屏,引脚上有小黑点的是COM口,其它是SEG口。看这块屏上有5个脚上有黑点,但实测其中一个有黑点的是SEG脚。 所以基本可以确定这块屏是4COM * 32SEG的屏。 用数码管的思维驱动是没法驱动的,因为在任意两点加电压都会同时亮起至少4处。 网上都说MCU驱动可以是可以,但会很复杂,而且效果不好,会有类似数码管的鬼影出现。 而且网上对控制原理的描述太少,不知道如何使其只亮起某一段,所以选择使用专用的驱动芯片 — HT1621B, tb上才9毛钱一块,因为是当玩具来玩,怎么简单怎么来,何必为难自己。 二、电路设计 三、焊接调试 四、程序 写命令时,数据格式为ID + 命令(b100 + 9bit命令。命令最低位任意); 写数据时,数据格式为ID + 地址 + 数据(b101 + 6bit地址 + 4bit数据)。在这里要注意地址为高位在前,数据为低位在前。 底层驱动 /* 所有字节只有低四位有效 array_RAM[0] : bit3-bit0: SEG0 - D3:D0 array_RAM[1] : bit3-bit0: SEG1 - D3:D0 array_RAM[2] : bit3-bit0: SEG2 - D3:D0 ....... */ uint8_t array_RAM[32] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; /** * @brief 将N个bit命令发送给HT1621B * @note * @param * @retval None * @author PWH * @date 2021/6 */ static void ht1621b_write_command_bits(uint8_t command, uint8_t num_of_bits) { int8_t i; for (i = 0; i < num_of_bits; i++) { GPIO_WriteLow(HT1621B_WR_GPIO, HT1621B_WR_PIN); if (command & 0x80) { GPIO_WriteHigh(HT1621B_DATA_GPIO, HT1621B_DATA_PIN); } else { GPIO_WriteLow(HT1621B_DATA_GPIO, HT1621B_DATA_PIN); } GPIO_WriteHigh(HT1621B_WR_GPIO, HT1621B_WR_PIN); command <<= 1; } } /** * @brief 将N个bit数据发送给HT1621B * @note * @param * @retval None * @author PWH * @date 2021/6 */ static void ht1621b_write_data_bits(uint8_t data, uint8_t num_of_bits) { int8_t i; for (i = 0; i < num_of_bits; i++) { GPIO_WriteLow(HT1621B_WR_GPIO, HT1621B_WR_PIN); if (data & 0x01) { GPIO_WriteHigh(HT1621B_DATA_GPIO, HT1621B_DATA_PIN); } else { GPIO_WriteLow(HT1621B_DATA_GPIO, HT1621B_DATA_PIN); } GPIO_WriteHigh(HT1621B_WR_GPIO, HT1621B_WR_PIN); data >>= 1; } } /** * @brief 向HT1621B发送一个命令 * @note * @param * @retval None * @author PWH * @date 2021/6 */ static void ht1621b_write_one_command(uint8_t command) { GPIO_WriteLow(HT1621B_CS_GPIO, HT1621B_CS_PIN); ht1621b_write_command_bits(0x80, 3); //发送标识码 100 ht1621b_write_command_bits(command, 9); //发送9位命令,前8位为命令,最后1位任意 GPIO_WriteHigh(HT1621B_CS_GPIO, HT1621B_CS_PIN); } /** * @brief 将一个数据写入HT1621B某一个地址 * @note * @param * @retval None * @author PWH * @date 2021/6 */ static void ht1621b_write_one_addr_data(uint8_t address, uint8_t data) { GPIO_WriteLow(HT1621B_CS_GPIO, HT1621B_CS_PIN); ht1621b_write_command_bits(0xA0, 3); //发送标识码 101 ht1621b_write_command_bits(address << 2, 6); //发送6位地址 ht1621b_write_data_bits(data, 4); GPIO_WriteHigh(HT1621B_CS_GPIO, HT1621B_CS_PIN); } /** * @brief 连续写入多个数据到HT1621B * @note * @param * @retval None * @author PWH * @date 2021/6 */ static void ht1621b_write_N_addr_data(uint8_t address, uint8_t *array, uint8_t len) { uint8_t i; GPIO_WriteLow(HT1621B_CS_GPIO, HT1621B_CS_PIN); ht1621b_write_command_bits(0xA0, 3); //发送标识码 101 ht1621b_write_command_bits(address << 2, 6); //发送6位地址 for (i = 0; i < len; i++) { ht1621b_write_data_bits(*array++, 4); } GPIO_WriteHigh(HT1621B_CS_GPIO, HT1621B_CS_PIN); } /** * @brief * @note * @param * @retval None * @author PWH * @date 2021/6 */ void ht1621b_init(void) { GPIO_Init(HT1621B_DATA_GPIO, HT1621B_DATA_PIN, GPIO_MODE_OUT_PP_HIGH_FAST); GPIO_Init(HT1621B_WR_GPIO, HT1621B_WR_PIN, GPIO_MODE_OUT_PP_HIGH_FAST); GPIO_Init(HT1621B_CS_GPIO, HT1621B_CS_PIN, GPIO_MODE_OUT_PP_HIGH_FAST); GPIO_Init(HT1621B_RD_GPIO, HT1621B_RD_PIN, GPIO_MODE_IN_PU_NO_IT); ht1621b_write_one_command(0x29); //1/3 bias,4commons ht1621b_write_one_command(0x01); //SYS EN ht1621b_write_one_command(0x03); //LCD ON } /** * @brief 将缓冲区的数据写入HT1621B,在while中不断循环 * @note * @param * @retval None * @author PWH * @date 2021/6 */ void ht1621b_scan(void) { ht1621b_write_N_addr_data(0, array_RAM, 32); } 因为不知道屏引脚对应的段,所以需要用程序测出对应关系,得 /* bit7 - bit0: f g e d a b c x (x为任意,这里强制为0) */ const uint8_t array_num[11] = { // 0 1 2 3 4 5 6 7 8 9 NULL 0xbe, 0x06, 0x7c, 0x5e, 0xc6, 0xda, 0xfa, 0x0e, 0xfe, 0xde, 0x00 }; const uint8_t array_char[2] = { // A P 0xee, 0xec }; 驱动程序 /** * @brief 6个大数字 * @note * @param * @retval None * @author PWH * @date 2021/6 */ void ht1621b_display_big_8(uint8_t which, uint8_t num) { if (num > 10) return; switch(which) { case big_num_1: array_RAM[6] = array_num[num] >> 4; //只有低四位有效,数字的f g e d array_RAM[5] &= 0x01; //清零a b c 的位置 array_RAM[5] |= array_num[num]; //数字的a b c break; case big_num_2: array_RAM[4] = array_num[num] >> 4; array_RAM[3] &= 0x01; array_RAM[3] |= array_num[num]; break; case big_num_3: array_RAM[2] = array_num[num] >> 4; array_RAM[1] &= 0x01; array_RAM[1] |= array_num[num]; break; case big_num_4: array_RAM[0] = array_num[num] >> 4; array_RAM[8] &= 0x01; array_RAM[8] |= array_num[num]; break; case big_num_5: array_RAM[9] = array_num[num] >> 4; array_RAM[10] &= 0x01; array_RAM[10] |= array_num[num]; break; case big_num_6: array_RAM[11] = array_num[num] >> 4; array_RAM[12] &= 0x01; array_RAM[12] |= array_num[num]; break; } } /** * @brief 蓝牙 * @note * @param * @retval None * @author PWH * @date 2021/6 */ void ht1621b_display_bluetooth(uint8_t sta) { array_RAM[27] &= ~0x01; if (sta) { array_RAM[27] |= 0x01; } } |
|
|
|
只有小组成员才能发言,加入小组>>
3309 浏览 9 评论
2988 浏览 16 评论
3490 浏览 1 评论
9049 浏览 16 评论
4083 浏览 18 评论
1167浏览 3评论
601浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
592浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2329浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1892浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-18 21:38 , Processed in 1.107787 second(s), Total 48, Slave 39 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号