历史上的今天
今天是:2024年12月04日(星期三)
2019年12月04日 | KS0108_AVR驱动[0617]
2019-12-04 来源:eefocus
前几天,一直在玩这个,
因为RAM读时序的问题,因为proteus仿真的问题...
本来简单的东西也会被拖很久的。。。
这里仅列出代码,注释什么的有时间再不上吧。
开发平台为IAR EWAVR 5.20(编译/硬件调试) + SlickEdit(编辑) + Proteus(软件仿真),但是为了尽量保证可一直性,并没有使用IAR特有的位操作的形式,只需稍加改动,即可移植到winavr或iccavr上,
另外proteus请不要使用忙位检测,不要使用超过4mhz的时钟,高版本可选内部4mhz的时钟
这些感觉是proteus的问题,就像1602也是不能检测忙位一样,不是我程序的问题!
示例中的main函数实现了隔点画点的功能,仅此而已。
但对于这款芯片来说最重要的其实就是画点了!
/*
AVR KS0108 DRIVERLIB
*/
/*
Definition of the PORTS
*/
#include #include #include "jlib.h" #define KS0108_PORT_DATA PORTB #define KS0108_PORT_CONTROL PORTC #define KS0108_DDR_DATA DDRB #define KS0108_DDR_CONTROL DDRC #define KS0108_PIN_DATA PINB #define KS0108_PIN_CONTROL PINC /* Definition of the PORTS for Bit Operation */ #define KS0108_RS 0 #define KS0108_RW 1 #define KS0108_CS1 2 #define KS0108_CS2 3 #define KS0108_ENABLE 4 #define KS0108_RESET 5 /* */ #define KS0108_CMD_ON 0x3F #define KS0108_CMD_OFF 0x3E #define KS0108_ROW_BASE 0xC0 #define KS0108_COLUMN_BASE 0x40 #define KS0108_PAGE_BASE 0xB8 #define KS0108_STATE_BUSY 7 #define KS0108_STATE_SHOW 5 #define KS0108_STATE_RESET 4 void ks0108_init(void); unsigned char ks0108_get_state(void); //得到LCD状态字 unsigned char ks0108_busy_test(void); void ks0108_exec_cmd(unsigned char command); //发送命令字 void ks0108_on(void); //打开LCD void ks0108_off(void); void ks0108_set_row(unsigned char); void ks0108_set_page(unsigned char); void ks0108_set_column(unsigned char); void ks0108_write_data(unsigned char,unsigned char); unsigned char ks0108_read_data(unsigned char); void ks0108_draw_point(unsigned char ,unsigned char ); int main(void) { int i,j; ks0108_init(); ks0108_on(); j=0; for(i=0;i<128;i++) { for(;j<64;j+=2) ks0108_draw_point(i,j); if(j==64) j=1; else j=0; } return 0; } void ks0108_init() { KS0108_DDR_CONTROL=0xFF; KS0108_DDR_DATA=0xFF; KS0108_PORT_DATA=0xFF; j_clrbit(KS0108_PORT_CONTROL,KS0108_RESET); //j_us(2); KS0108_PORT_CONTROL=0xFF; } unsigned char ks0108_get_state() { // unsigned char data=0; KS0108_DDR_DATA=0; KS0108_PORT_DATA=0xFF; j_clrbit(KS0108_PORT_CONTROL,KS0108_ENABLE); j_setbit(KS0108_PORT_CONTROL,KS0108_RW); j_clrbit3(KS0108_PORT_CONTROL,KS0108_RS,KS0108_CS1,KS0108_CS2); //j_us(2); j_setbit(KS0108_PORT_CONTROL,KS0108_ENABLE); data=KS0108_PIN_DATA; //j_us(2); j_clrbit(KS0108_PORT_CONTROL,KS0108_ENABLE); //j_us(2); j_setbit2(KS0108_PORT_CONTROL,KS0108_CS1,KS0108_CS2); return data; } unsigned char ks0108_busy_test() { unsigned char state=0; state=ks0108_get_state(); if(state&KS0108_STATE_BUSY) { //BUSY return 1; } else { //idle return 0; } } void ks0108_on() { //while(ks0108_busy_test()); //j_us(2); ks0108_exec_cmd(KS0108_CMD_ON); } void ks0108_off() { //while(ks0108_busy_test()); //j_us(2); ks0108_exec_cmd(KS0108_CMD_OFF); } void ks0108_set_row(unsigned char row) { row|=KS0108_ROW_BASE; //while(ks0108_busy_test()); //j_us(2); ks0108_exec_cmd(row); } void ks0108_set_column(unsigned char column) { column|=KS0108_COLUMN_BASE; //while(ks0108_busy_test()); //j_us(2); ks0108_exec_cmd(column); } void ks0108_set_page(unsigned char page) { page|=KS0108_PAGE_BASE; //while(ks0108_busy_test()); //j_us(2); ks0108_exec_cmd(page); } void ks0108_exec_cmd(unsigned char cmd) { //while(ks0108_busy_test()); //j_us(2); KS0108_DDR_DATA=0xFF; j_clrbit(KS0108_PORT_CONTROL,KS0108_ENABLE); j_clrbit2(KS0108_PORT_CONTROL,KS0108_CS1,KS0108_CS2); j_clrbit2(KS0108_PORT_CONTROL,KS0108_RW,KS0108_RS); KS0108_PORT_DATA=cmd; //j_us(2); j_setbit(KS0108_PORT_CONTROL,KS0108_ENABLE); //j_us(2); j_clrbit(KS0108_PORT_CONTROL,KS0108_ENABLE); //j_us(2); j_setbit2(KS0108_PORT_CONTROL,KS0108_CS1,KS0108_CS2); } void ks0108_write_data(unsigned char data,unsigned char left_right) { //写显示数据 //while(ks0108_busy_test()); //j_us(2); KS0108_DDR_DATA=0xFF; //j_clrbit(KS0108_PORT_CONTROL,KS0108_ENABLE); if(left_right==1) { //选择左半屏 j_clrbit(KS0108_PORT_CONTROL,KS0108_CS1); j_setbit(KS0108_PORT_CONTROL,KS0108_CS2); } else { //选择右半屏 j_setbit(KS0108_PORT_CONTROL,KS0108_CS1); j_clrbit(KS0108_PORT_CONTROL,KS0108_CS2); } j_clrbit(KS0108_PORT_CONTROL,KS0108_RW); j_setbit(KS0108_PORT_CONTROL,KS0108_RS); KS0108_PORT_DATA=data; //j_us(2); j_setbit(KS0108_PORT_CONTROL,KS0108_ENABLE); //j_us(2); j_clrbit(KS0108_PORT_CONTROL,KS0108_ENABLE); //j_us(2); j_setbit2(KS0108_PORT_CONTROL,KS0108_CS1,KS0108_CS2); } unsigned char ks0108_read_data(unsigned char left_right) { unsigned char data=0; //while(ks0108_busy_test()); //j_us(2); KS0108_DDR_DATA=0; KS0108_PORT_DATA=0xFF; j_clrbit(KS0108_PORT_CONTROL,KS0108_ENABLE); if(left_right==1) { //选择左半屏 j_clrbit(KS0108_PORT_CONTROL,KS0108_CS1); j_setbit(KS0108_PORT_CONTROL,KS0108_CS2); } else if(left_right==0) { //选择右半屏 j_setbit(KS0108_PORT_CONTROL,KS0108_CS1); j_clrbit(KS0108_PORT_CONTROL,KS0108_CS2); } j_setbit(KS0108_PORT_CONTROL,KS0108_RW); j_setbit(KS0108_PORT_CONTROL,KS0108_RS); //j_us(2); j_setbit(KS0108_PORT_CONTROL,KS0108_ENABLE); //j_us(2); j_clrbit(KS0108_PORT_CONTROL,KS0108_ENABLE); //j_us(2); j_setbit(KS0108_PORT_CONTROL,KS0108_ENABLE); data=KS0108_PIN_DATA; //j_us(2); j_clrbit(KS0108_PORT_CONTROL,KS0108_ENABLE); //j_us(2); j_setbit2(KS0108_PORT_CONTROL,KS0108_CS1,KS0108_CS2); return data; } ///////// void ks0108_draw_point(unsigned char x,unsigned char y) { unsigned char column=0,page=0; unsigned char left_right=1; unsigned char data=0; if(x<=63) { column=x; } else { column=x-64; left_right=0; } page=y/8; data=~(1<<(y%8)); ks0108_set_page(page); ks0108_set_column(column); data&=ks0108_read_data(left_right); ks0108_set_page(page); ks0108_set_column(column); ks0108_write_data(data,left_right); } 另外其中用到jlib.h中的几个以j打头的宏定义为自己写的一些简化用的东西 也发布下 //1226_2008 AVR_INCJ elite version 0.13 //波特率 #define BAUDRATE 19200 //时钟频率 #define F_CPU ((double)4000000) //延时 微秒 #define j_us(x) __delay_cycles((long)(F_CPU*(double)((x)/1000000.0))) //延时 毫秒 #define j_ms(x) __delay_cycles((long)(F_CPU*(double)((x)/1000.0))) //延时 空指令 #define j_nop() __no_operation() //全局中断开,简化 #define j_sei() __enable_interrupt() //全局中断关,简化 #define j_cli() __disable_interrupt() //置位 #define j_setbit(tmp,x) ((tmp)|=(1<<(x))) //置双位 #define j_setbit2(tmp,x,y) ((tmp)|=(1<<(x))|(1<<(y))) //置三位 #define j_setbit3(tmp,x,y,z) ((tmp)|=(1<<(x))|(1<<(y))|(1<<(z))) //清位 #define j_clrbit(tmp,x) ((tmp)&=(~(1<<(x)))) //清双位 #define j_clrbit2(tmp,x,y) ((tmp)&=(~(1<<(x)))&(~(1<<(y)))) //清三位 #define j_clrbit3(tmp,x,y,z) ((tmp)&=(~(1<<(x)))&(~(1<<(y)))&(~(1<<(z)))) //位检测1 #define j_bit_pos(tmp,x) ((tmp)&(x)) //位检测0 #define j_bit_neg(tmp,x) (~((tmp)|~(x))) //循环左移,=号两边都为volatile型时慎用 #define j_round_left(tmp,x) ((tmp)=((tmp)<<(x))|((tmp)>>(8-(x)))) //循环右移,=号两边都为volatile型时慎用 #define j_rount_right(tmp,x) ((tmp)=((tmp)>>(x))|((tmp)<<(8-(x))))
史海拾趣
|
值班室八防区无线报警器是一款通用型很强的报警设备,可以方便地组成一个家居保安系统,并且能和其它无线报警探头组网使用,功能扩展非常方便。 值班室八防区无线报警器标准配置由主机、无线门磁、遥控器和电源组成。这是 ...… 查看全部问答> |
|
看图,该图是一音频的低音加重电路中的一部份,前面已有过不少低频滤波电路,全不是这种形式,这又加一这样的电路,真不明白是啥意思。 说明:这电路中的电阻R67和R66是同一可调电阻,另串一固定电阻,在这里为了仿真全改为固定电阻了。R10也是。 ...… 查看全部问答> |
|
这个“时髦”的电话拥有一个曲柄的摇棒,还有一个滑出的数字键盘,听筒和话筒基本上移植了古老的电话形式,但是这个手机需要一个50磅重的电池提供能量,看完之后小编觉得超级的雷人啊!… 查看全部问答> |
|
wince6下,建立一个模拟器,BSP为DEVICEEMULATOR,加了CELLCORE组件,使用ENFORA.在调用lineopen时返回LINEERR_OPERATIONFAILED。 不知是什么原因,应该从哪方面入手来解决这个问题? 请各位大侠给予帮助和指导,谢谢。… 查看全部问答> |
|
tinyxml.lib(tinystr.obj) : module machine type \'MIPS\' conflicts with target machine type \'X86\',怎么办呢,谢谢… 查看全部问答> |
|
最近在做一个录音系统,想法录音文件存在sd卡上,参考st IAR-STM32-SKMP3_player的范例,发现只有读取文件没有写入文件,按照自己的理解增加代码,搞了好几天结果总是写不成功,仿真代码运行又都正常,请香主指导一下。我的代码如下:&nb ...… 查看全部问答> |




