单片机课程设计总结

累死人的单片机课程设计终于结束了,忙了两天多。就是个数码管+ADC。看看自己两年多前写的程序。。这感觉。用了一天多重构。。。。之前写程序的那个乱啊。。。重新整理下,自己的库函数。记录于此。


1602库函数

1602.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/*模 块 名:                LCD1602      */

/*创 建 人:ikuoy 日期:2014-11-04 */

/*修 改 者:js 日期:2016-07-08 */

/*版 本2.1 */

/*使用方法:首先调用LCD初始化函数void LcdInit();
输入一个double类型数据调用void LcdDisplay(double temp);
显示在第二行;如需修改第一行数据可在LcdDisplay函数中修改 */
/* BUG : 第二行double数据显示最后一位后,会跟随一位乱码 */


#include <stc12c5a60s2.h>
#include <intrins.h>
#include <stdio.h>
#include <math.h>
#define uint unsigned int
#define uchar unsigned char

sbit lcdrs = P1^7;
sbit lcden = P2^4;
sbit rw = P1^6;

#define lcd_data_port P0




void sdelay(uint s); //通用延迟函数

void write_com(uchar com); //并口写数据
void write_data(uchar date); //并口写数据

void LcdInit(); //1602初始化

void LcdDisplay(double temp,uint t); //显示函数

1602.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
//1602.c
include <1602.h>

/*模 块 名: LCD1602 */

/*创 建 人:ikuoy 日期:2014-11-04 */

/*修 改 者:js 日期:2016-07-08 */

/*版 本2.1 */



/**********************************************/
void sdelay(uint s) //通用延迟函数
{
uint x,y;
for(x=s;x>0;x--)
for(y=250;y>0;y--);
}
/**********************************************/
void write_com(uchar com) //并口写数据
{
lcdrs=0;
lcden=0;
lcd_data_port=com;
sdelay(1);
lcden=1;
sdelay(1);
lcden=0;
}
void write_data(uchar date) //并口写数据
{
lcdrs=1;
lcden=0;
lcd_data_port=date;
sdelay(1);
lcden=1;
sdelay(1);
lcden=0;
}


/*********************************************************************
*
* 函 数 名: LcdInit
* 功能描述: LCD初始化
* 函数说明: 初始化数据:0x38 0x0c 0x06 0x01
* 调用函数: sdelay(),write_com(), write_data()
* 输 入: 无
* 返 回: 无
* 设 计 者:ikuoy 日期:2014-12-23
* 版 本: 1.0
***********************************************************************/
void LcdInit() //1602初始化
{
lcden=0;
rw=0;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
}

/*********************************************************************
*
* 函 数 名: LcdDisplay
* 功能描述: LCD显示
* 函数说明: double类型数据转化为字符串,在lcd第二行显示。
* 调用函数: sprintf(),write_com(),sdelay()
* 全局变量: 无
* 输 入: 一个double类型变量值
* 返 回: 无
* 设 计 者:ikuoy 日期:2014-12-23
* 修 改 者:js 日期:2016-07-08
* 版 本: 2.0
***********************************************************************/


void LcdDisplay(double temp,uint t) //显示函数
{
static uchar table0[]={"pm "}; //1602默认第一行
static uchar table1[]={"00.0 "};

uchar num=0;

sprintf(table1,"%f",(double)temp);
sprintf(table1+8,"%2d",(uint)t);


write_com(0x80);
for(num=0;num<15;num++) //第一行刷新
{
write_data(table0[num]);
sdelay(5);
}


write_com(0x80+0x40);
for(num=0;num<16;num++) //第二行显示
{write_data(table1[num]); //0.0195
sdelay(5);
}
}

数码管

  • 对应电路图如下
    QQ.jpg

shu.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/*模 块 名:           数码管           */

/*创 建 人:ikuoy 日期:2014-07-01 */

/*版 本1.2 */

/*使用方法:调用 Shu_Display(double js)函数,输入一个double类型数据,
固定显示格式为小数点前4位及小数点后两位。 */

/*BUG:显示小数点后第二位时,有时会与输入值小1.原因疑似与fmod()函数有关 */

#include <stc12c5a60s2.h>
#include <intrins.h>
#include <stdio.h>
#include <math.h>
#define uint unsigned int
#define uchar unsigned char


//端口定义
#define io_dm P0 //定义LED显示的段码数据脚
sbit io_shu = P2^3; //数码管开关低电平有效
sbit io_A = P2^0; //3-8译码器输入
sbit io_B = P2^1;
sbit io_C = P2^2;

sbit io_DP = P0^7; //dp点定义


extern uchar du_num[15];


void delay_1ms(uchar x); //1ms延迟函数

void wei(uchar i); //位选输出函数

void Shu_Display(double js);//数码管显示函数

shu.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include <shu.h>

/*模 块 名: 数码管 */

/*创 建 人:zy 日期:2014-07-01 */

/*版 本1.2 */

//显示数字
uchar du_num[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
// 0 1 2 3 4 5 6 7 8 9 a b c d e f



void delay_1ms(uchar x)//1ms延迟函数
{
uchar j;
while(x--){
for(j=0;j<125;j++)
{;}
}
}

void wei(uchar i) //位选信号输入
{ //i=i+1;
switch (i)
{ case 0:{io_A=0;io_B=0;io_C=0;} break;
case 1:{io_A=1;io_B=0;io_C=0;} break;
case 2:{io_A=0;io_B=2;io_C=0;} break;
case 3:{io_A=1;io_B=1;io_C=0;} break;
case 4:{io_A=0;io_B=0;io_C=1;} break;
case 5:{io_A=1;io_B=0;io_C=1;} break;
case 6:{io_A=0;io_B=1;io_C=1;} break;

default: ; break;
}

}


/*********************************************************************
*
* 函 数 名: Shu_Display()
* 功能描述: 将数字显示到数码管上,显示格式4+2
* 函数说明: 段选位选,动态刷新数码管
* 调用函数: delay_1ms fmod()
* 全局变量: 无
* 输 入: 1个double类型数据
* 返 回: 无
* 设 计 者:ikuoy 日期:2014-07-01
* 修 改 者:ikuoy 日期:2016-07-08
* 版 本: 1.2
***********************************************************************/
void Shu_Display(double js)
{uchar i; //循环变量
static uchar suff[6]; //数据处理暂存数组
static uint cuff[4]; //提取各位有关
static double n=1,y; //与小数截取有关
static uint count; //暂存

y=fmod(js,n); //分离js小数部分 存在y中

count=js; //强制类型转换,取js整数部分

suff[0] = count/1000; //取千位
cuff[0] = count%1000;

suff[1] = cuff[0]/100; //取百位
cuff[1] = cuff[0]%100;

suff[2] = cuff[1]/10; //取十位
suff[3] = cuff[1]%10; //取个位

count = y*1000; //小数部分。扩大1000倍提取。

cuff[2] = count%1000;

suff[4] = cuff[2]/100; //小数点后一位
cuff[3] = cuff[2]%100;

suff[5] = cuff[3]/10; //小数点后2位

io_shu=0; //打开3-8译码器

for(i=0;i<6;i++)
{
wei(i); //位选
io_dm=du_num[suff[i]];//段选
if(i==3) io_DP=1;
delay_1ms(1); //延迟
}

}