admin 管理员组文章数量: 1086019
2024年3月6日发(作者:laravel和tp框架怎么选择)
第一课时
1、 Holtek公司编译器HT-IDE3000使用说明
(1) 双击打开HT-IDE3000,进入编译器的界面,见下图:
(2) 单击“工程”——>选择“新建”,弹出下图窗口;
——Project Name:新建项目文件的名称,不建议使用中文名称;
——Project Location:项目文件存放的位置,勾选“Create directory for project”后,会自动建立一个文件夹,项目文件都存放在此文件夹内;
——Project MCU:单片机的型号;
——Choose Language Tool:选择编程语言,这里选择“V2”版本的C语言。
(3) 点击下一步,选择“.C”;
(4) 点击下一步,再点击下一步,点击OK,然后弹出“配置选项”,配置选择只要是对单片机一些功能和特性进行设置,例如工作电压,工作频率,看门狗等;
(5) 配置选项设置完后,点击OK,再点击确定,那么新的工程就建立完毕了。
2、 C语言程序设计
(1) 主函数
每个程序只有一个主函数,程序是从主函数开始执行。
格式:void main()
{
}
例子:
#include "HT66F40.h"
void main() //程序从这里开始跑
{
}
_nop();
_nop();
_nop();
//语句1
//语句2
//语句3
功能说明:程序执行的顺序,语句1—>语句2—>语句3。
(2) 子函数
一个程序包含各种功能,如果每种功能都做成一个子函数,那么整个程序的架构实现了模块化。
例如,LCD的开启,显示及关闭这三个功能可以分别做成三个独立的子函数。
使用子函数的步骤:
① 编写子函数的功能
void TurnOn_LCD() //LCD开启子函数,TurnOn_LCD是函数的名称
{
}
_nop();
_nop();
//这里先用空指令代表子函数的功能
//这里先用空指令代表子函数的功能
② 声明子函数,告诉单片机有这个子函数存在
void TurnOn_LCD();
技巧:直接把步骤① 的第一行复制过来,然后在后面加上分号;
③ 调用子函数
TurnOn_LCD();
例子:
#include "HT66F40.h"
void TurnOn_LCD(); //声明子函数,告诉单片机有这个子函数存在
void TurnOff_LCD(); //声明子函数,告诉单片机有这个子函数存在
void display_LCD(); //声明子函数,告诉单片机有这个子函数存在
void main()
{
_nop(); //空指令
_nop(); //空指令
_nop(); //空指令
while(1) //while循环结构,当小括号里内容为真,执行
{ //while大括号里的内容
TurnOn_LCD(); //调用LCD开启子函数
display_LCD(); //调用LCD显示子函数
TurnOff_LCD(); //调用LCD关闭子函数
}
}
void TurnOn_LCD() //编写子函数的功能,LCD开启子函数,TurnOn_LCD是
{ //函数的名称
_nop(); //这里先用空指令代表子函数的功能
_nop(); //这里先用空指令代表子函数的功能
}
void TurnOff_LCD() //编写子函数的功能,LCD关闭子函数,TurnOff_LCD是
{ //函数的名称
_nop(); //这里先用空指令代表子函数的功能
_nop(); //这里先用空指令代表子函数的功能
}
void display_LCD()
{
_nop();
_nop();
}
//编写子函数的功能,LCD显示子函数,display_LCD是
//函数的名称
//这里先用空指令代表子函数的功能
//这里先用空指令代表子函数的功能
(3) 中断子函数
使用中断子函数的步骤:
① 相关寄存器进行初始化(请查阅相关型号IC的PDF)
② 声明中断子函数地址
格式:#pragma vector 中断子函数名称 @中断入口地址
例如:
#pragma vector isr_tm0 @0x14
③ 编写中断子函数的功能
例如:
void isr_tm0()
{
}
例子:
#include "HT66F40.h"
#pragma vector isr_tm0 @0x14 //声明中断子函数的入口地址
void mcu_init(); //声明单片机初始化子函数
void main()
{
mcu_init();
while(1)
{
_nop();
_nop();
}
}
//while循环结构,当小括号里内容为真,执行while
//大括号里的内容
void isr_tm0()
{
_t0af=0;
_nop();
}
void mcu_init()
{
//编写中断子函数的功能
//清除中断标志位
//这里先用空指令代表中断子函数的功能
//编写单片机初始化子函数
//定时器相关寄存器初始化
_tm0c0=0b00000000; //定时器计数时钟fsys/4=1Mhz,fsys=4Mhz为系统
//频率
_tm0c1=0b11000001; //选择定时计数工作模式,
//清0计数器的条件:与比较器A匹配,即
//计数值与tm0al,tm0ah的值相等时,计数器清0)
_tm0al=0xe8; //0x03e8=1000
_tm0ah=0x03;
_t0on=1; //启动定时器
}
//定时器中断相关寄存器初始化
_emi=1; //总中断控制位,0-关闭 1-开启
_mf0e=1; //多功能中断0控制位,0-关闭 1-开启
_t0ae=1; //TM0比较器A匹配中断控制位,0-关闭 1-开启
(4) 函数的返回值及参数的介绍
① 无返回值,无参数函数:前面介绍的函数均为无返回值无参数函数。
例如:
void main()
{
}
void表示此函数是“空类型”(无返回值),void是“空”的意思,即执行
此函数后不产生一个函数值。
② 有返回值,有参数函数
例如:
程序功能说明:
参数的传递:调用函数时,程序把a赋值给x,b赋值给y;因为a和b的数据类型是u8,所以参数x和y的数据类型也是u8。
返回值 :子函数max调用完之后,通过return(z);语句把函数值z返回给主函数,即c=max(a,b);等价于c=z; ;因为c的数据类型为u8,所以函数返回值的类型也是u8。
u8 max(u8 x,u8 y)——第一个u8为函数返回值类型,其余为参数的数据类型。
#include "HT66F40.h"
#define u8 unsigned char
u8 a,b,c;
u8 max(u8 x,u8 y);
void main()
{
}
//程序中u8与unsigned char 等价
//声明变量a,b,c
//声明函数max,函数功能为比较两个数大小
a=3; //3赋值给变量a
b=4; //4赋值给变量b
while(1) //while循环结构,当小括号里内容为真,执行while大括号
{ //里的内容
_nop(); //空指令
_nop(); //空指令
c=max(a,b); //max函数调用
}
u8 max(u8 x,u8 y) //max函数功能的编写
{
u8 z;
z=x>y?x:y;
return(z);
}
③ 无返回值,有参数函数
例如:显示功能函数,
#include “ht66f40.h”
#define u8 unsigned char
u8 display_data;
void display(display_data);
void main()
{
while(1)
{
display(0x55);
}
}
void display(display_data)
{
_nop(); //显示的实际功能先用空指令代替
_nop(); //显示的实际功能先用空指令代替
}
功能说明;函数调用时,把显示的数据0x55通过参数传递给display_data;显示完毕后,并不需要返回一个函数值,因此函数的返回类型为空。
//定义变量z,只在max函数里才有效
//如果x大于y,z=x;反之,z=y;
//返回z的值给主函数
3、 常量、变量及变量的数据类型介绍
(1) 常量
① 以实际的数值出现在程序里面
例如:二进制常量 0b10101010
十进制常量 170
十六进制常量 0xAA
② 符号常量
在程序中,用一个符号来表示一个常量。
例如:#define time 50 //程序中,用time来表示50这个常量
③ 查表常量
const unsigned char tab[10]={
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09};
——数据存放在单片机ROM里面,10代表有10个数;
——tab[0]表示第一个数,tab[1]表示第二个数……tab[9]表示第十个数。
(2) 变量及其数据类型
① 程序执行过程中,需要暂存一些数据,例如标志位,执行次数,AD采样数
据等,因此就需要定义变量来储存这些数据的。
由于变量占用ROM空间或RAM空间,因此在使用变量前,需要定义变量的数据类型,以便让编译器配置存放变量的空间。
② 基本数据类型
Size(bits)
Type(数据类型) 范围大小
bit
unsigned char
unsigned int
unsigned long
1
8
16
32
0,1
0~255或0~0xFF
0~65535或0~0xFFFF
0~4294967295或0~0xFFFFFFFF
例如:bit flag; //声明一个名称为flag的位变量
unsigned char temp1; //声明一个名称为temp1的字节变量
unsigned int temp2; //声明一个名称为temp2的双字节变量
unsigned long temp3; //声明一个名称为temp3的四字节变量
temp1=10; //变量的赋值,
temp2=0x09; //变量的赋值,
注:变量声明时,如果没有进行初始化,那么变量的值是随机的。
③ 构造数据类型
数组是指由同一种基本数据类型的数组成的一组数据。
例如:unsigned char tab[10]={}; //声明一个名称为tab的数组,它是由10
//个字节变量组成的。
//这10个变量分别是tab[0]、tab[1]……tab[9]
数组在声明时不能进行初始化,需用户在主函数里进行初始化。
例如:
unsigned char i; //声明一个字节变量
unsigned char tab[10];
for(i=0;i<10;i++)
{
tab[i]=0;
}
//声明一个长度为10的字节变量数组
//for循环结构,请参考下面章节
//上述代码等于tab[0]=0;tab[1]=0;……tab[9]=0
④ 变量命名规则
——第一个字符必须是英文字母或底线符号”_”,之后可紧接字母或数字。
——变量名不能超过32个字符。
——英文字母的大小写是有区别的。
例如:count,count2,_count,_count2
⑤ 变量的有效范围
——定义在函数里面,变量有效范围在此函数范围内。
——定义在函数外面,变量有效范围是整个程序。
《第一课时总结》——案例1
#include “ht66f50.h”
#define u8 unsigned char
#define u16 unsigned int
#define u32 unsigned long
#define time 50
#pragma rambank0
bit flag1;
bit flag2;
u8 i;
u8 count;
u8 temp1;
u16 temp2;
u32 temp3;
u8 tab[10];
void mcu_init();
void main(void)
{
mcu_init();
while(1)
{
flag1=0;
flag2=1;
count=time;
temp1=0xff;
temp2=0xffff;
temp3=0xffffffff;
//程序中出现u8,实际会用unsigned char代替
//程序中出现u16,实际会用unsigned int代替
//程序中出现u32,实际会用unsigned long代替
//程序中出现time,实际会用50代替
//把下面定义的变量都存放在RAM的区域0
//声明位变量flag1
//声明位变量flag2
//声明字节变量i
//声明字节变量count
//声明字节变量temp1
//声明双字节变量temp2
//声明四字节变量temp3
//声明长度为10的字节变量数组
//声明子函数,单片机初始化
//调用子函数,单片机初始化
//把0赋值给flag1
//把1赋值给flag2
//把time赋值给count,实际是把50赋值给count
//把0xff赋值给temp1
//把0xffff赋值给temp2
//把0xffffffff赋值给temp3
}
}
void mcu_init()
{
_acerl=0x00;
_cp0c=0x08;
_cp1c=0x08;
for(i=0;i<10;i++)
{
tab[i]=0;
}
}
//单片机初始化子函数的编写
//AD通道都作为普通I/O口功能
//关闭比较器0
//关闭比较器1
//数组初始化
第二课时
1、C程序架构
(1)C语言的程序是由语句所组成,每条语句的最后必须有分号“;”做为结束符。
① 函数及变量的声明语句;
例如:void mcu_init(); //声明子函数语句
bit flag1; //声明变量语句
② 表达式语句,执行数学及逻辑运算;
例如:temp1=0xff; //赋值语句
Temp1=temp1-100; //减法运算语句
temp=a||b;
temp={a&&b)>c;
表达式和表达式语句的区别:
表达式:由运算符和数据构成的式子
例如:a a+1 a&&b 表达式语句:见前面②说明。 ③ 函数调用语句,执行函数的功能 例如:mcu_init(); //子函数调用语句 ④ 程序中还包含一些前置预处理指令,它们后面不需要加分号“;”作为结束符。 例如: #include “ht66f50.h” #define u8 unsigned char //程序中出现u8,实际会用unsigned char代替 #define time 50 //程序中出现time,实际会用50代替 #pragma rambank0 //把下面定义的变量都存放在RAM的区域0 (2)运算符 ① 数学运算符 + - * / ② ③ % 分别为加法,减法,乘法,求商,求余 比较运算符 两个数比较,如果成立,运算结果为真(1);否则,运算结果为假(0)。 > 大于 //例如a>b,如果a大于b,则结果为1;否则结果为0 >= 大于或等于 //参考上述 < 小于 //参考上述 <= 小于或等于 //参考上述 == 等于 //参考上述 != 不等于 //参考上述 逻辑运算符 取运算符两边数据的真假值做逻辑运算,运算结果是真(1)或假(0)。 && 与运算 //0xf0&&0x00=0;0xf0&&0x08=1; || 或运算 //0xf0||0x00=1; 0x00||0x00=0; ④ ! 非运算 //!0xf0=0; !0=1; 位逻辑运算符 两个数位与位进行操作。 & 位与 //0b11111111&0b10101010=0b10101010; //1&1=1;1&0=0;0&1=0;0&0=0; //两个1为1,其余为0 | ^ ~ 位或 //0b11111111|0b10101010=0b11111111; //1|1=1;1|0=1;0|1=1;0|0=0; //两个0为0,其余为1 //0b11111111^0b10101010=0b01010101; //1^1=0;1^0=1;0^0=0; //相同为0,不同为1 //~1=0;~0=1; //0b10101010>>1=0b01010101;右移1位 //0b10101010<<1=0b01010100;左移1位 位异或 位取反 向右移位 向左移位 >> << 2、程序流程控制 (1)if选择结构(2选1选择结构) ① if(条件表达式) {语句1;} //如果条件表达式为真,执行语句1; else {语句2;} //如果条件表达式为假,执行语句2; ——小技巧:如果没有语句2,else可以忽略不写。 例如: #include “ht66f40.h” #define u8 unsigned char //程序中出现u8,实际会用unsigned char代替 #define u16 unsigned int #define u32 unsigned long #pragma rambank0 bit flag; u8 count; void main() { flag=1; //把1赋值给位变量flag while(1) { if(flag!=1) //如果位变量flag不等于1 { count=2; //执行把2赋值给字节变量count } } } else { count=3; } //如果位变量flag等于1 //执行把3赋值给字节变量count ② if语句嵌套:要注意哪个括号是属于哪个if或else的 格式: if(表达式1) //如果表达式1为真,执行if大括号里的内容 { //即执行语句1和第二个if语句 语句1; if(表达式2) //如果表达式2为真,执行if大括号里的内容 { //即执行语句2 语句2; } else { 语句3; } } else { } 语句4; //如果表达式2为假,,执行else大括号里的内容 //即执行语句3 //如果表达式1为假,执行else大括号里的内容 //即执行语句4 (2)switch(表达式) //多选1选择结构 { case 常量表达式1:语句1;break; case 常量表达式2:语句2;break; case 常量表达式3:语句3;break; …… default: break; //其他 } 功能说明:根据switch后面括号表达式的值来选择执行哪一个case后面的语 句,执行到break;程序会跳出switch结构。 例如: #include “ht66f50.h” #define u8 unsigned char //程序中出现u8,实际会用unsigned char代替 #define u16 unsigned int #define u32 unsigned long #define time 50 #pragma rambank0 bit flag1; bit flag2; u8 count; u8 temp1; u16 temp2; u32 temp3; void mcu_init(); void main(void) { //把下面定义的变量都存放在RAM的区域0 //声明子函数,单片机初始化 mcu_init(); //调用子函数,单片机初始化 while(1) { temp1=2; switch(temp1) { case 1: count=10;break; //如果temp1==1;执行 case 2: count=20;break; //如果temp1==2;执行 case 3: count=30;break; //如果temp1==3;执行 default: break; //如果temp1是其他值,执行 } } } void mcu_init() { _acerl=0x00; _cp0c=0x08; _cp1c=0x08; } (2)循环结构 ①while循环 while(表达式) {语句;} 功能说明:判断表达式是否成立; ——成立执行语句; ——不成立跳出while循环; 例如:while(1) { } ②for循环 for(表达式1;表达式2;表达式3;) {语句;} 功能说明:先执行表达式1; 判断表达式2是否成立; ——成立执行语句,执行表达式3,跳回判断表达式2是否成立; ——不成立跳出for循环; 例如: unsigned char i; //声明一个字节变量 unsigned char tab[10]; //声明一个长度为10的字节变量数组 for(i=0;i<10;i++) //for循环结构,请参考下面章节 { tab[i]=0; } 《第二课时总结》——案例2 软件功能:用定时器实现1分钟的计时,用2位数码管显示。
版权声明:本文标题:Holtek C语言学习教程 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/b/1709717314a543957.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论