1. 问题描述

目前在手写笔项目中需要使用一块LCD来显示个人信息和当前工作状态等

2. 问题分析

2.1 芯片资料

查看数据说手册中的图,看到如何

看到这个数据格式为:【地址+控制字+数据字】
从 m 和 n 的格式上看:是支持一次从批量的数据的

  1. 地址需要看SA0的接线方式:
  2. 控制就是读写数据位有效 参考代码为 0x00 和 0x40

屏幕厂商的电路图如下:

厂商给的驱动程序参考:

// 各个引脚对应的高低由单片机IO口控制
#ifdef Interface_IIC/**********************************************
//
//IIC通信开始函数
//
**********************************************/
void IC_IIC_Start()
{SDA = high;SCL = high;_nop_();SDA = low;_nop_();_nop_();SCL = low;
}/**********************************************
//
//IIC通信停止函数
//
**********************************************/
void IC_IIC_Stop()
{SDA = low;_nop_();SCL = high;_nop_();_nop_();SDA = high;
}/**********************************************
//
//向IIC写数据函数
//返回值为acknowledgement位信号
//
**********************************************/
bit Write_IIC_Data(uchar Data)
{unsigned char i;bit Ack_Bit; //应答信号for (i = 0; i < 8; i++){SDA = (bit)(Data & 0x80);_nop_();SCL = high;_nop_();_nop_();SCL = low;Data = _crol_(Data, 1);}SDA = high; //释放IIC SDA总线为主器件接收从器件产生应答信号_nop_();_nop_();SCL = high; //第9个时钟周期_nop_();_nop_();Ack_Bit = SDA; //读取应答信号SCL = low;return Ack_Bit;
}/**********************************************
//
//写命令函数**********************************************/
void Write_Command(uchar command)
{IC_IIC_Start();Write_IIC_Data(Slave_Address); //Salve AdressWrite_IIC_Data(OP_Command);    //写命令Write_IIC_Data(command);IC_IIC_Stop();
}/**********************************************
//
//写数据函数
//
**********************************************/
void Write_Data(uchar date)
{IC_IIC_Start();Write_IIC_Data(Slave_Address); //Salve AdressWrite_IIC_Data(OP_Data);       //写数据Write_IIC_Data(date);IC_IIC_Stop();
}#endifvoid init_program()
{Write_Command(0xAE); //Display OFF (sleep mode)Write_Command(0xD5); //Set Display Clock Divide Ratio/Oscillator FrequencyWrite_Command(0x52); //320kHz //101hz    52Write_Command(0xA8); //Set Multiplex RatioWrite_Command(0x0f); //16Write_Command(0xD3); //Set Display OffsetWrite_Command(0x00); //Write_Command(0x40); //Set Display Start LineWrite_Command(0x8D); //Set Display OffsetWrite_Command(0x14); //VCC Generated by Internal DC/DC CircuitWrite_Command(0xA0); //Set Segment Re-mapWrite_Command(0xC0); //Set COM Output Scan DirectionWrite_Command(0xDA); //Set COM Pins Hardware ConfigurationWrite_Command(0x02); //Write_Command(0x81); //Set Contrast ControlWrite_Command(0x30);Write_Command(0xD9); //Set Pre-charge PeriodWrite_Command(0xf1); //VCC Supplied ExternallyWrite_Command(0xDB); //Set VCOMH Deselect LevelWrite_Command(0x20); //0x3CWrite_Command(0xA4); //Output follows RAM contentWrite_Command(0xA6); //Set Normal Displaydisplay_white();Write_Command(0xAF); //Set Display ON (normal mode)
}void Reset_IC()
{Delay_Ms(10);// LED_Work = low;RES = low;Delay_Ms(50);RES = high;Delay_Ms(100);//  VCC_Change = high;
}void display_white(void)
{unsigned int j, i;for (i = 0xB0; i < 0xB2; i++){Write_Command(i);Write_Command(0x00);Write_Command(0x12);for (j = 0; j < 96; j++)Write_Data(0xff);}
}void main()
{Reset_IC();init_program();display_white();
}

2.2 51822 驱动移植

此芯片使用的II接口的方式驱动,在51822的资料中使用的是TWI接口

  • 库文件
  • 打开库的配置宏 (此处参考库的demo中关于配置的打开)

// <e> TWI_ENABLED - nrf_drv_twi - TWI/TWIM peripheral driver
//==========================================================
#ifndef TWI_ENABLED
#define TWI_ENABLED 1
#endif
#if  TWI_ENABLED
// <o> TWI_DEFAULT_CONFIG_FREQUENCY  - Frequency// <26738688=> 100k
// <67108864=> 250k
// <104857600=> 400k #ifndef TWI_DEFAULT_CONFIG_FREQUENCY
#define TWI_DEFAULT_CONFIG_FREQUENCY 26738688
#endif// <q> TWI_DEFAULT_CONFIG_CLR_BUS_INIT  - Enables bus clearing procedure during init#ifndef TWI_DEFAULT_CONFIG_CLR_BUS_INIT
#define TWI_DEFAULT_CONFIG_CLR_BUS_INIT 0
#endif// <q> TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT  - Enables bus holding after uninit#ifndef TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT
#define TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT 0
#endif// <o> TWI_DEFAULT_CONFIG_IRQ_PRIORITY  - Interrupt priority// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
// <0=> 0 (highest)
// <1=> 1
// <2=> 2
// <3=> 3 #ifndef TWI_DEFAULT_CONFIG_IRQ_PRIORITY
#define TWI_DEFAULT_CONFIG_IRQ_PRIORITY 3
#endif// <e> TWI0_ENABLED - Enable TWI0 instance
//==========================================================
#ifndef TWI0_ENABLED
#define TWI0_ENABLED 1
#endif
#if  TWI0_ENABLED
// <q> TWI0_USE_EASY_DMA  - Use EasyDMA (if present)#ifndef TWI0_USE_EASY_DMA
#define TWI0_USE_EASY_DMA 0
#endif#endif //TWI0_ENABLED
// </e>// <e> TWI1_ENABLED - Enable TWI1 instance
//==========================================================
#ifndef TWI1_ENABLED
#define TWI1_ENABLED 0
#endif
#if  TWI1_ENABLED
// <q> TWI1_USE_EASY_DMA  - Use EasyDMA (if present)#ifndef TWI1_USE_EASY_DMA
#define TWI1_USE_EASY_DMA 0
#endif#endif //TWI1_ENABLED
// </e>// <e> TWI_CONFIG_LOG_ENABLED - Enables logging in the module.
//==========================================================
#ifndef TWI_CONFIG_LOG_ENABLED
#define TWI_CONFIG_LOG_ENABLED 0
#endif
#if  TWI_CONFIG_LOG_ENABLED
// <o> TWI_CONFIG_LOG_LEVEL  - Default Severity level// <0=> Off
// <1=> Error
// <2=> Warning
// <3=> Info
// <4=> Debug #ifndef TWI_CONFIG_LOG_LEVEL
#define TWI_CONFIG_LOG_LEVEL 3
#endif// <o> TWI_CONFIG_INFO_COLOR  - ANSI escape code prefix.// <0=> Default
// <1=> Black
// <2=> Red
// <3=> Green
// <4=> Yellow
// <5=> Blue
// <6=> Magenta
// <7=> Cyan
// <8=> White #ifndef TWI_CONFIG_INFO_COLOR
#define TWI_CONFIG_INFO_COLOR 0
#endif// <o> TWI_CONFIG_DEBUG_COLOR  - ANSI escape code prefix.// <0=> Default
// <1=> Black
// <2=> Red
// <3=> Green
// <4=> Yellow
// <5=> Blue
// <6=> Magenta
// <7=> Cyan
// <8=> White #ifndef TWI_CONFIG_DEBUG_COLOR
#define TWI_CONFIG_DEBUG_COLOR 0
#endif#endif //TWI_CONFIG_LOG_ENABLED
// </e>#endif //TWI_ENABLED// <q> APP_TWI_ENABLED  - app_twi - TWI transaction manager#ifndef APP_TWI_ENABLED
#define APP_TWI_ENABLED 1
#endif
  • 配置初始化接口
/*******************************************************************************
* Function Name  : sxb_lcd_init
* Description    : 手写笔 LCD 接口初始化
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void sxb_lcd_bsp_init(void)
{uint32_t ret;/* 初始化IIC总线 */nrf_drv_twi_config_t const config = {.scl = LCD_SCL_PIN,.sda = LCD_SDA_PIN,.frequency = NRF_TWI_FREQ_400K,.interrupt_priority = APP_IRQ_PRIORITY_LOWEST,.clear_bus_init = false,};APP_TWI_INIT(&m_app_twi, &config, MAX_PENDING_TRANSACTIONS, ret);APP_ERROR_CHECK(ret);/* 初始化自己的管脚 */nrf_gpio_cfg_output(LCD_RST_PIN);nrf_gpio_pin_clear(LCD_RST_PIN);nrf_gpio_pin_set(LCD_RST_PIN);
}

要想使用TWI接口需要了解的核心结构体

typedef struct {uint8_t * p_data;     ///< Pointer to the buffer holding the data.uint8_t   length;     ///< Number of bytes to transfer.uint8_t   operation;  ///< Device address combined with transfer direction.uint8_t   flags;      ///< Transfer flags (see @ref APP_TWI_NO_STOP).
} app_twi_transfer_t;typedef struct {app_twi_callback_t         callback;///< User-specified function to be called after the transaction is finished.void *                     p_user_data;///< Pointer to user data to be passed to the callback.app_twi_transfer_t const * p_transfers;///< Pointer to the array of transfers that make up the transaction.uint8_t                    number_of_transfers;///< Number of transfers that make up the transaction.
} app_twi_transaction_t;

app_twi_transaction_t : 这个结构体定义N次读写操作
app_twi_transfer_t:一次读写操作配置

写一次数据对应的用法如下:

/*******************************************************************************
* Function Name  : lcd_write_cmd_cb
* Description    : LCD 写命令接口(是缓存接口,不能连续使用)
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void lcd_write_cmd(uint8_t cmd)
{m_lcd_sbuf[0] = LCD_REG_C;m_lcd_sbuf[1] = cmd;/* 设置每个序列的内容 */lcd_transfers.operation = APP_TWI_WRITE_OP(LCD_ADDR);lcd_transfers.p_data = m_lcd_sbuf;lcd_transfers.length = 2;lcd_transfers.flags = 0;/* 设置传输序列 */lcd_transaction.callback = lcd_write_cmd_cb;lcd_transaction.p_user_data = m_lcd_sbuf + 1;lcd_transaction.p_transfers = &lcd_transfers;lcd_transaction.number_of_transfers = 1;APP_ERROR_CHECK(app_twi_schedule(&m_app_twi, &lcd_transaction));
}

写多条数据对应的操作如下:

/*******************************************************************************
* Function Name  : sxb_lcd_bsp_setting
* Description    : LCD 配置显示参数接口
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void sxb_lcd_bsp_setting(void)
{uint8_t i;/* 设置初始化序列 */for (i = 0; i <= 21; i++){init_transfers[i].operation = APP_TWI_WRITE_OP(LCD_ADDR);init_transfers[i].p_data = (uint8_t *)&lcd_init_setting[i];init_transfers[i].length = 2;if (i == 21)init_transfers[i].flags = APP_TWI_NO_STOP;elseinit_transfers[i].flags = 0;}/* 设置传输序列 */lcd_transaction.callback = lcd_setting_cb;lcd_transaction.p_user_data = NULL;lcd_transaction.p_transfers = init_transfers;lcd_transaction.number_of_transfers = 22;/* 启动传输 */APP_ERROR_CHECK(app_twi_schedule(&m_app_twi, &lcd_transaction));
}

注意:发送指令的数据缓存需要单独存起来,这个参数在启动传输之前都没有实际的数据交互,在回调执行前不能随意修改缓存的数据,否则可能会导致数据异常

同厂商沟通过可以采用批量写数据

/*******************************************************************************
* Function Name  : sxb_lcd_dis_screen
* Description    : LCD 刷屏函数
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void sxb_lcd_dis_screen(void)
{uint8_t i;static lcd_cmd_t lcd_dat_setting[8];/* 刷新LCD */for (i = 0; i < 2; i++){// cmd 0xbxlcd_dat_setting[4 * i + 0].type = LCD_REG_C;lcd_dat_setting[4 * i + 0].cmd = 0xb0 + i;init_transfers[4 * i + 0].operation = APP_TWI_WRITE_OP(LCD_ADDR);init_transfers[4 * i + 0].p_data = (uint8_t *)&lcd_dat_setting[4 * i + 0];init_transfers[4 * i + 0].length = 2;init_transfers[4 * i + 0].flags = APP_TWI_NO_STOP;// cmd 0x00lcd_dat_setting[4 * i + 1].type = LCD_REG_C;lcd_dat_setting[4 * i + 1].cmd = 0;init_transfers[4 * i + 1].operation = APP_TWI_WRITE_OP(LCD_ADDR);init_transfers[4 * i + 1].p_data = (uint8_t *)&lcd_dat_setting[4 * i + 1];init_transfers[4 * i + 1].length = 2;init_transfers[4 * i + 1].flags = APP_TWI_NO_STOP;// cmd 0x12lcd_dat_setting[4 * i + 2].type = LCD_REG_C;lcd_dat_setting[4 * i + 2].cmd = 0x12;init_transfers[4 * i + 2].operation = APP_TWI_WRITE_OP(LCD_ADDR);init_transfers[4 * i + 2].p_data = (uint8_t *)&lcd_dat_setting[4 * i + 2];init_transfers[4 * i + 2].length = 2;init_transfers[4 * i + 2].flags = APP_TWI_NO_STOP;/* 这个是设置刷新缓存 */sxb_lcd_tcb.pbuf[97 * i] = LCD_REG_D;init_transfers[4 * i + 3].operation = APP_TWI_WRITE_OP(LCD_ADDR);init_transfers[4 * i + 3].p_data = sxb_lcd_tcb.pbuf + 97 * i;init_transfers[4 * i + 3].length = 97; // 这个数据是批量送的init_transfers[4 * i + 3].flags = APP_TWI_NO_STOP;}/* 设置传输序列 */lcd_transaction.callback = lcd_screen_cb;lcd_transaction.p_user_data = NULL;lcd_transaction.p_transfers = init_transfers;lcd_transaction.number_of_transfers = 8;/* 启动传输 */APP_ERROR_CHECK(app_twi_schedule(&m_app_twi, &lcd_transaction));
}

【项目笔记_手写笔】在51822 上移植SSD1306驱动相关推荐

  1. 苹果键盘怎么手写_手写笔的魅力

    请点击文末右下角"",移步官网获取更好阅读体验! 欢迎加入Augix官方QQ群:595698697. 喜讯!Augix已开通微博,请搜索关注:Augix频道. B站视频更新频道也已 ...

  2. 驰为 hi12 linux,驰为Hi12双系统 手写笔让操作更精准

    驰为Hi12双系统配备手写笔,大家对于手写笔应该不会很陌生,手写笔在平板上面的应用还不是很广泛,手写笔能够感知笔尖的压力,在使用时做出相应的变化.当你用力按压时,所绘制出的线条就会变粗,轻轻用力则会比 ...

  3. 接口传输带格式的文字和图片_除了看书爽,这款带手写笔的「电纸书」还是办公利器...

    在电子书阅读器的基础上,iReader Smart X 增加了很多方便办公的特性. 电子书阅读器因为省电.护眼等特性,被很多人买来看书.看文档.电子书阅读器不断更新迭代,市面上也出现了一些支持手写的产 ...

  4. iphone降级_今年 iPhone 将支持手写笔?乔老爷哭了!

    9102年,你希望 iPhone 加手写笔么?? 是不是很多同学都选择的「不希望」 咆哥其实对于苹果支持手写笔这件事一直不太赞同,毕竟这违背了乔老爷的初心呀!根据花旗研究(Citi Research) ...

  5. markdown 菜单 折叠_疑似三星Z Fold 3折叠屏手机专利公布 带有S pen手写笔存储槽_手机行情...

    华强北电脑网10月30日消息 好像很多人对于三星note系列标配的S-Pen非常喜欢,同样对于三星Galaxy Z Fold系列折叠屏手机一样喜爱,可是二者不能兼得,目前只能二者选其一.但是现在有好消 ...

  6. 苹果键盘怎么手写_我们可能都低估手写笔的价值了 | 硬哲学

    还记得上一次握着手写笔,在触控屏上写字是什么时候的事吗? 触控笔或许可以算作是「时代的眼泪」中的一颗,这个因触屏而诞生,也因触屏而衰落的产物,似乎在如今我们的眼中变成了过时的物件. 如果不是三星对自家 ...

  7. iphone个系列尺寸_乔帮主再被打脸,库克觉得iPhone将需要手写笔

    随着2019年一晃已经来到8月,三星下半年的机皇Galaxy Note 10系列已经蓄势待发的情况下,近日根据爆料显示,此次在Galaxy Note 10系列上的特色配件S-Pen,或将会被赋予更多的 ...

  8. 华为p50pro会不会搭载鸿蒙系统,华为p50pro有没有手写笔_华为p50pro会不会用手写笔...

    华为即将上市的华为p50pro这款手机现在已经获得了非常多的热度,那么这款手机它是不是用手写笔的呢?接下来我们就一起来了解一下华为p50pro它是不是配备了手写笔吧. 1.华为p50pro有没有手写笔 ...

  9. thinkpad触控笔怎么用_【ThinkPad X1 Yoga 2018笔记本电脑使用总结】键盘|手写笔|显示|触控板_摘要频道_什么值得买...

    ThinkPad X1 Yoga 2018笔记本电脑使用总结(键盘|手写笔|显示|触控板) 1.键盘 这篇原创全程有X1 Yoga 2018完成,X1的键盘手感应该来说很不错,比目前在用的MD223的 ...

最新文章

  1. layui一个表格中怎么接两个接口的值_layer学习笔记之table表格引入数据实现分页...
  2. Linux环境编译安装OpenJDK
  3. 自定义类似于listView中Item背景
  4. selenium - webdriver常用方法
  5. Hadoop书籍和网络资源介绍
  6. python代码自动格式化_代码的自动格式化
  7. 关于两个php.ini的说明
  8. ADO 连接数据库的几种方式
  9. 数据结构实验 7.兔子与樱花
  10. python实现knn分类_KNN图像分类及Python实现
  11. gparted调整分区大小_CentOS Linux系统中用parted分区命令分区
  12. 微信开发,调用js-SDK接口
  13. Python3 人脸识别 源码
  14. FOC 电流环PI控制器出来后为什么是电压?整定参数跟电机参数有关系吗?
  15. Python经典书籍推荐
  16. html表单设计姓名性别,编写一个表单页面census.html,让用户填写姓名、性别(男女选择)、兴趣(运动,读书,音乐,书法及其他)...
  17. 三角形主机linux,受热捧的三角形主机是什么?我来为你解析
  18. 为什么RGB要转换成HSV
  19. canvas+html实现视频弹幕,可以全屏实现
  20. Linux多定时器的实现之一

热门文章

  1. (转载)分享 别人的 职业故事
  2. VR技术原理分析,【VR原理入门理论篇】
  3. [POI2015]WIL-Wilcze doły(单调队列)
  4. Jordan 块的几何
  5. 【华为OD机试 2022】 冠亚军排名,奖牌榜排名(C++ Java JavaScript Python)
  6. 一个基于Tensorflow的神经网络机器翻译系统
  7. 《网上图书销售系统》功能需求 建立“顾客建立图书订单”的顺序图
  8. Proxmox周期掉线 网卡驱动异常修复
  9. org.springframework.dao.DataIntegrityViolationException错误
  10. C++第3次实验(基础班)—选择结构程序设计(参考答案)-项目1:个人所得税计算器