arm力天电子 lpc2148流水灯驱动程序详解

一个破流水灯程序看了两天了,void WriteByte(unsigned char data)这部分还是没看懂,力天电子上面介绍说这部分三端口的数据输入,选出8位的串行数据。

选择16,17,18,19四个控制位,主要跟电路图的连接有关,4块74HC595,组成32位(如图所示),从下往上依次是0~31为,图中写反了。因此到D13对应的引脚应该是16,D12对应的是17,D11对应的是18,D10对应的是19. 当16,17,18,19分别为低电平时二极管才能够导通发光。高电平时熄灭

1#include

2#define         SCLK  0x01<<24  //指定P1.24管脚,通过 IO1DIR |= SCLK;可判断是IO1端口,而不是IO0端口
3#define         MISO  0x01<<5    //指定P0.5口
4#define         MOSI  0x01<<6   //指定P0.6口
5#define         RCK   0x01<<7  //指定P0.7口
6void Delayn(unsigned long n);  //unsigned long n是一个入口函数
7void HC595_Init(void);
8void Write595(void);
9unsigned int HC595_DATA = 0;
10int main(void)
11{
 12 //初始化74HC595
 13 HC595_Init();
14  //主循环
15  while(1)
16  {

17    HC595_DATA &=~(1<<16);Write595();  //首先1左移16位,得到0000 0000 0000 0001 0000 0000 0000 0000,取反(~)得到1111 1111 1111 1110 1111 1111 1111 1111

    //然后跟HC595_DATA取与(&),HC595_DATA的值为0xFFFFFFFF(在42行),得到1111 1111 1111 1110 1111 1111 1111 1111 //此处取与的目的是为了保证在改变16位的同时不会影响到其他位。之后跳转到60行执行Write595(),依次写入第一个八位,0xff。写入第二个八位,0xff。写入第三个八位,0xfe。写入第四个八位,0xff  因此写入的32位数据就是0xfffeffff  (16位为0)

18    Delayn(250000);  //延迟,使D13发亮一段时间

19    HC595_DATA &=~(1<<17);Write595(); //类似于上面,最终得到的是1111 1111 1111 1101 1111 1111 1111 1111 写入的32位数据时0xfffdffff  (17位为0)
 20   Delayn(250000);   //延迟,使D12发亮一段时间
 21   HC595_DATA &=~(1<<18);Write595(); //类似于上面,最终得到的是1111 1111 1111 1011 1111 1111 1111 1111 写入的32位数据时0xfffbffff  (18位为0)
22    Delayn(250000);   //延迟,使D12发亮一段时间
23    HC595_DATA &=~(1<<19);Write595();//类似于上面,最终得到的是1111 1111 1111 0111 1111 1111 1111 1111 写入的32位数据时0xfff7ffff  (19位为0)
24   Delayn(250000);  
 //延迟,使D10发亮一段时间 
    

25    HC595_DATA |=(1<<16);Write595(); 
26    Delayn(250000); //D13灭
27    HC595_DATA |=(1<<17);Write595(); 
28    Delayn(250000);  //D12灭
29   HC595_DATA |=(1<<18);Write595();
30   Delayn(250000);  //D11灭
31   HC595_DATA |=(1<<19);Write595();
32   Delayn(250000);  //D10灭
33  }
34}

35//初始化595接口
36void HC595_Init(void)  //初始化IO口
37{
38  IO0DIR |= MOSI|RCK; //此处可以换一种写法IO0DIR |= (1<<6)|(1<<7),方向寄存器设置成输出
39  IO1DIR |= SCLK;  //方向寄存器设置成输出
40  IO1CLR |= SCLK;
41 // IO0DIR |= RCK; (可以不要)
  
42  HC595_DATA = 0xFFFFFFFF;  Write595(); //HC595_DATA = 0xFFFFFFFF的作用是置595所有的端口为高电平,使所有的发光二级管熄灭
43}
44//写字节(此处的功能不是很懂,希望有知道的朋友可以指点!)
45void WriteByte(unsigned char data)  //unsigned char data是一个入口函数
46{
47  unsigned char i;
48  //IO0CLR = RCK; (可以不要,62已经声明过了)
49  for(i=0;i<8;i++)
50  {
51    if(data&0x01)      IO0SET=MOSI;
52    else      IO0CLR=MOSI;
53    IO1SET=SCLK;  //时钟高电平
54    data>>=1;  //数据移位,把数据移到串行端口
55    IO1CLR=SCLK;  //时钟低电平
56  }
57  //IO0SET = RCK; (可以不要,67已经声明过了)
58}


59//刷新595的数据
60void Write595(void)   //第一步595片选,然后数据写入第一个八位(0-7),再数据写入第二个八位(8-15),第三个八位(16-23),第四个八位(24-31)
61{
62  IO0CLR = RCK;                     //595片选
63  WriteByte(HC595_DATA&0xff);   //写入第一个八位,0xff  然后跳转到45行执行WriteByte
64  WriteByte((HC595_DATA&0xff00)>>8);//写入第二个八位,0xff  然后跳转到45行执行WriteByte
65  WriteByte((HC595_DATA&0xff0000)>>16); //写入第三个八位,0xfe  然后跳转到45行执行WriteByte
66  WriteByte((HC595_DATA&0xff000000)>>24);//写入第四个八位,0xff  然后跳转到45行执行WriteByte
67  IO0SET = RCK;
68}
69//延时周期数   
70void Delayn(unsigned long n)     //()里面不能是void,因为此处有一个入口函数unsigned long n
71{
72  while(n--);

73}



你可能感兴趣的:(ARM嵌入式)