板子上使用了74lv164作为io的串行并处的扩展来驱动3个数码管LED。原理图如下
从两张图可以阐述链接的io顺序不是你想的那样有规律,因此需要做个表格来
分别将0…9的数据段统计出来
include
include
include
include
include
include
include
include
include
include
include
include
include
include
include
include
include
include
include
include
include
include
include
include
include
include
include
include
include
include
include
define DEVICE_NAME “led”
include “74LV164.h”
//#define debug
/*
CPU Board s3c6410
samsung s3c6410 74lv164
GPI0 7SEG_CLK 57
GPI2 7SEG_DATA 61
GPI4 7SEG_CLR 59
*/
unsigned char data[]={0xc0,0xcf,0x64,0x46,0x4b,0x52,0x50,0xc7,0x40,0x42,0x41};//led 0,1,…9
void init_74lv764_port(void){
unsigned int reg_value;
__raw_writel(0x55555555,S3C64XX_GPICON);
PORTI=0xFFFFFFFF;
__raw_writel(0xFFFFFFFF,S3C64XX_GPIDAT);
printk("S3C64XX_GPIDAT %08x",__raw_readl(S3C64XX_GPIDAT));
printk("S3C64XX_GPICON %08x",__raw_readl(S3C64XX_GPICON));
reg_value=readl(S3C64XX_GPICON);
reg_value=(reg_value & (~((0x03 << 0 )| (0x03 << 2 )| (0x03 <<4 ))));//port0,port2,port4
reg_value |= ((0x01 << 0 )| (0x01 << 2 )| (0x01 <<4 ));//set port 0,2,4 output
writel(reg_value,S3C64XX_GPICON);
CLR_1;
DI_1;
CLK_1;
}
void delay_ms(UI16_T Counter){
while(Counter–);
}
/*
* Loads a byte into the shift register (74’164).
*
* Parameters:
* out_byte The byte to load into the ‘164.
*/
void
led_load_byte(uint8_t out_byte)
{
/* make sure clock is low */
CLK_0;
int i;
for(i=0; i<8; i++)
{
/* loop through bits */
if (out_byte & 0x80)
{
/* this bit is high */
DI_1;
}
else
{
/* this bit is low */
DI_0;
}
out_byte = out_byte << 1;
/* pulse the the shift register clock */
CLK_1;
delay_ms(20000);
CLK_0;
}
}
ssize_t s3c6410_led_write(struct file *filp,const char __user *buf,size_t dontcare,loff_t *f_pos){
return 1;
}
static long s3c6410_led_ioctl(struct file *filp, unsigned int cmd, unsigned long arg){
return 0;
}
static struct file_operations dev_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = s3c6410_led_ioctl,
.write = s3c6410_led_write,
};
static struct miscdevice misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &dev_fops,
};
static int __init dev_init(void){
int ret;
int i;
unsigned char address[6];
init_74lv764_port();
for(i=0;i<11;i++){
led_load_byte(data[i]);
mdelay(2000);
}
ret = misc_register(&misc);
printk (DEVICE_NAME"\t initialized \n");
return ret;
}
static void __exit dev_exit(void){
misc_deregister(&misc);
writel(0x00,S3C64XX_GPIDAT);
printk (DEVICE_NAME “\tdev_exit\n”);
}
module_init(dev_init);
module_exit(dev_exit);
MODULE_LICENSE(“GPL”);
MODULE_AUTHOR(“gary Inc.”);
简单测试了下,在insmod 下循环送出LED数