//原创程序,如需转载或借用,请注明出处!
前几天,一直在玩这个,
因为RAM读时序的问题,因为proteus仿真的问题...
本来简单的东西也会被拖很久的。。。
这里仅列出代码,注释什么的有时间再不上吧。
开发平台为IAR EWAVR 5.20(编译/硬件调试) + SlickEdit(编辑) + Proteus(软件仿真),但是为了尽量保证可一直性,并没有使用IAR特有的位操作的形式,只需稍加改动,即可移植到winavr或iccavr上,
另外proteus请不要使用忙位检测,不要使用超过4mhz的时钟,高版本可选内部4mhz的时钟
这些感觉是proteus的问题,就像1602也是不能检测忙位一样,不是我程序的问题!
示例中的main函数实现了隔点画点的功能,仅此而已。
但对于这款芯片来说最重要的其实就是画点了!
Code
/*
AVR KS0108 DRIVERLIB
*/
/*
Definition of the PORTS
*/
#include<ioavr.h>
#include<intrinsics.h>
#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);
}
/*
AVR KS0108 DRIVERLIB
*/
/*
Definition of the PORTS
*/
#include<ioavr.h>
#include<intrinsics.h>
#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打头的宏定义为自己写的一些简化用的东西
也发布下
Code
//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))))
//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))))