前面已经讲了C语言基础,从此以后将进行编程实战。C数据类型名较长,编程输入不太方便。
下面编写一个定义数据类型别名的程序,并定义实现后面例程常用到的位操作及字符串操作函数。
1. 打开前面教程中创建的C51 Template.uvproj。新建两个文件分别以mtype.h,mytype.c存于C51 Template文件夹下的Library文件夹中。
2. 完成mtype.h
2.1 输入如下宏语句,以避免重复包含时编译出错,并在文件开头添加包含文件信息的注释。
/*mytype.h
Designed by Bill Liu
Version 0.0
Modified last by Bill Liu on 10/31/2021
*/
#ifndef __MYTYPE_H_
#define __MYTYPE_H_
#endif
2.2 添加包含Keil C函数库并注释起来。当需用到时取消注释即可。
/*mytype.h
Designed by Bill Liu
Version 0.0
Modified last by Bill Liu on 11/23/2022
*/
#ifndef __MYTYPE_H_
#define __MYTYPE_H_
#include <math.h>
//#include <stdlib.h>
//#include <stdio.h>
//#include <ctype.h>
//#include <string.h>
//#include <intrins.h>
#endif
2.3 定义数据类型别名,下面使用typedef定义别名。别名定义时,分别定义了大小写别名,这样可避免使用别名时,没注意到大小写时编译出错。如下:
/*mytype.h
Designed by Bill Liu
Version 0.0
Modified last by Bill Liu on 11/23/2022
*/
#ifndef __MYTYPE_H_
#define __MYTYPE_H_
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <intrins.h>
#ifndef BYTE
typedef unsigned char BYTE;
#endif
#ifndef byte
typedef unsigned char byte;
#endif
#ifndef ui8
typedef unsigned char ui8;
#endif
#ifndef UI8
typedef unsigned char UI8;
#endif
#ifndef U8
typedef unsigned char U8;
#endif
#ifndef u8
typedef unsigned char u8;
#endif
#ifndef uchar
typedef unsigned char uchar;
#endif
#ifndef INT8
typedef signed char INT8;
#endif
#ifndef int8
typedef signed char int8;
#endif
#ifndef I8
typedef signed char I8 ;
#endif
#ifndef i8
typedef signed char i8;
#endif
#ifndef WORD
typedef unsigned int WORD;
#endif
#ifndef word
typedef unsigned int word;
#endif
#ifndef UINT
typedef unsigned int UINT;
#endif
#ifndef uint
typedef unsigned int uint;
#endif
#ifndef UI16
typedef unsigned int UI16;
#endif
#ifndef ui16
typedef unsigned int ui16;
#endif
#ifndef U16
typedef unsigned int U16;
#endif
#ifndef u16
typedef unsigned int u16;
#endif
#ifndef UINT16
typedef unsigned int UINT16;
#endif
#ifndef uint16
typedef unsigned int uint16;
#endif
#ifndef I16
typedef signed int I16;
#endif
#ifndef i16
typedef signed int i16;
#endif
#ifndef INT16
typedef signed int INT16;
#endif
#ifndef int16
typedef signed int int16;
#endif
#ifndef DWORD
typedef unsigned long DWORD;
#endif
#ifndef UINT32
typedef unsigned long UINT32;
#endif
#ifndef uint32
typedef unsigned long uint32;
#endif
#ifndef UI32
typedef unsigned long UI32;
#endif
#ifndef ui32
typedef unsigned long ui32;
#endif
#ifndef U32
typedef unsigned long u32;
#endif
#ifndef Ui32
typedef unsigned long Ui32;
#endif
#ifndef I32
typedef long signed int I32;
#endif
#ifndef i32
typedef signed long i32;
#endif
#ifndef INT32
typedef signed long INT32;
#endif
#ifndef int32
typedef signed long int32;
#endif
#ifndef FP32
typedef float FP32;
#endif
#ifndef fp32
typedef float fp32;
#endif
#ifndef F32
typedef float F32;
#endif
#ifndef Fp32
typedef float Fp32;
#endif
#ifndef f32
typedef float f32;
#endif
#ifndef F64
typedef double F64;
#endif
#ifndef f64
typedef double f64;
#endif
#ifndef FP64
typedef double FP64;
#endif
typedef enum
{
FALSE = 0,
TRUE = 1
}BOOL;
typedef enum
{
F11_0592MHz = 1, //11.0592MHz
F12MHz,
F18_432MHz, //18.432MHz
F20MHz,
F22_1184MHz, //22.1184MHz
F24MHz,
F27MHz,
F30MHz,
F33MHz,
F33_1776MHz //33.1776MHz
}FSYSCLOCK;
//function for operating data's bit
typedef enum //define char bit position range
{
pos0=0, //define bit0 position as 0
pos1, //define bit1 position as 1
pos2, //define bit2 position as 2
pos3, //define bit3 position as 3
pos4, //define bit4 position as 4
pos5, //define bit5 position as 5
pos6, //define bit6 position as 6
pos7 //define bit6 position as 6
} BITPOS;
/**********************************************************************
Function: SetBit(BYTE* pBYTE, BITPOS bPos);
Return value: changed byte value
Discription: set one bit of 8bits data as 1
Example:
BYTE tem = T4T3M; //define tem and read T4T3M register into tem
T4T3M = SetBit(&tem, pos0);
***********************************************************************/
BYTE SetBit(BYTE* pBYTE, BITPOS bPos);
/**********************************************************************
Function: ResetBit(BYTE* pBYTE, BITPOS bPos);
Return value: changed byte value
Discription: reset one bit of 8bits data as 0
Example:
BYTE tem = T4T3M; //define tem and read T4T3M register into tem
T4T3M = ResetBit(&tem, pos0);
***********************************************************************/
BYTE ResetBit(BYTE* pBYTE, BITPOS bPos);
/**********************************************************************
Function: SetBits(BYTE* pBYTE,BITPOS hBit,BITPOS lBit,BYTE mData);
Return value: changed byte value
Discription: change continue bits of 8bits data to mdata
Example:
BYTE tem = T4T3M; //define tem and read T4T3M register into tem
T4T3M = SetBits(&tem, 4, 2, 0x05);
***********************************************************************/
BYTE SetBits(BYTE* pBYTE,BITPOS hBit,BITPOS lBit,BYTE mData);
/**********************************************************************
Function: GetBit(i8 mData,BITPOS pos);
Return value: specified bit value
Discription: Get specified bit of char data
Example:
i8 tem = T4T3M; //define tem and read T4T3M register into tem
ui8 tem1;
tem1 = GetBit(tem, 4);
***********************************************************************/
ui8 GetBit(i8 mData,BITPOS pos);
/**********************************************************************
Function: GetBits(i8 mData,BITPOS hBit,BITPOS lBit);
Return value: specified bits value
Discription: Get specified continue bits of char data
Example:
i8 tem = T4T3M; //define tem and read T4T3M register into tem
ui8 tem1;
tem1 = GetBits(tem, 4, 2);
***********************************************************************/
ui8 GetBits(i8 mData,BITPOS hBit,BITPOS lBit);
/string function
/***********************************************************************
Function: UcarBToString(ui8 src,ui8* desString);
Return value: desString
Discription: covert binary places of an unsigned char data binary places to string
Example:
ui8 tem = 123;
ui8 mstr[9] = {0};
UcharBToString(tem,mstr);
***********************************************************************/
ui8* UcharBToString(ui8 src,ui8* desString);
/***********************************************************************
Function: BStringToUchar(ui8 src[],ui8* destData);
Return value
Discription: covert string made of binary character to unsigned char
Example:
ui8 mstr[9] = "10101";
ui8 tem;
BStringToUchar(mstr,&tem);
***********************************************************************/
ui8 BStringToUchar(ui8 src[],ui8* destData);
/***********************************************************************
Function: SubString(ui8* srcString,ui8* desString,ui8 startPos, ui8 size_n);
Return Value: desString(substring)
Discription:cut a string from destination string
Example:
ui8 str1[10] = "123459789";
ui8 mstr2[9] = {0};
SubString(str1,mstr2,2,4); //"3456"
***********************************************************************/
ui8* SubString(ui8* srcString,ui8* desString, ui8 startPos, ui8 size_n);
#endif
2.4 定义位操作函数。 单片机程序很大一部分是写寄存器,改变寄存器某位的值,但有的寄存器可以直接进行位读写,有的则不能.51单片机中寄存器地址可以被8整除的一般可以可以直接进行位读写,否则就不可以。不可以的,就需先将寄存器的值读入一个变量中,再改变变量对应需要改变的位,然后再将这个变量赋值给寄存器。如果每次都写这样的代码,就会比较费事。先写成库函数,到时直接调用就比较方便。
2.4.1 在mtype.h定义位操作函数。在定义函数前,先声明一个枚举型,以限制bit位的位置的取值范围。
//function for operating data's bit
typedef enum //define char bit position range
{
pos0=0, //define bit0 position as 0
pos1, //define bit1 position as 1
pos2, //define bit2 position as 2
pos3, //define bit3 position as 3
pos4, //define bit4 position as 4
pos5, //define bit5 position as 5
pos6, //define bit6 position as 6
pos7 //define bit6 position as 6
} BITPOS;
/**********************************************************************
Function: SetBit(BYTE* pBYTE, BITPOS bPos);
Return value: changed byte value
Discription: set one bit of 8bits data as 1
Example:
BYTE tem = T4T3M; //define tem and read T4T3M register into tem
T4T3M = SetBit(&tem, pos0);
***********************************************************************/
BYTE SetBit(BYTE* pBYTE, BITPOS bPos);
/**********************************************************************
Function: ResetBit(BYTE* pBYTE, BITPOS bPos);
Return value: changed byte value
Discription: reset one bit of 8bits data as 0
Example:
BYTE tem = T4T3M; //define tem and read T4T3M register into tem
T4T3M = ResetBit(&tem, pos0);
***********************************************************************/
BYTE ResetBit(BYTE* pBYTE, BITPOS bPos);
/**********************************************************************
Function: SetBits(BYTE* pBYTE,BITPOS hBit,BITPOS lBit,BYTE mData);
Return value: changed byte value
Discription: change continue bits of 8bits data to mdata
Example:
BYTE tem = T4T3M; //define tem and read T4T3M register into tem
T4T3M = SetBits(&tem, 4, 2, 0x05);
***********************************************************************/
BYTE SetBits(BYTE* pBYTE,BITPOS hBit,BITPOS lBit,BYTE mData);
/**********************************************************************
Function: GetBit(i8 mData,BITPOS pos);
Return value: specified bit value
Discription: Get specified bit of char data
Example:
i8 tem = T4T3M; //define tem and read T4T3M register into tem
ui8 tem1;
tem1 = GetBit(tem, 4);
***********************************************************************/
ui8 GetBit(i8 mData,BITPOS pos);
/**********************************************************************
Function: GetBits(i8 mData,BITPOS hBit,BITPOS lBit);
Return value: specified bits value
Discription: Get specified continue bits of char data
Example:
i8 tem = T4T3M; //define tem and read T4T3M register into tem
ui8 tem1;
tem1 = GetBits(tem, 4, 2);
***********************************************************************/
ui8 GetBits(i8 mData,BITPOS hBit,BITPOS lBit);
2.4.2 在mtype.c中实现定义函数。
//***********************************************************************/
BYTE SetBit(BYTE* pBYTE, BITPOS bPos)
{
*pBYTE |= 1 << bPos;
return *pBYTE;
}
//End of SetBit(BYTE* pBYTE, BITPOS bPos)
//***********************************************************************/
BYTE ResetBit(BYTE* pBYTE, BITPOS bPos)
{
*pBYTE &= ~(1 << bPos);
return *pBYTE;
}
//End of ResetBit(BYTE* pBYTE, BITPOS bPos)
//***********************************************************************/
BYTE SetBits(BYTE* pBYTE,BITPOS hBit,BITPOS lBit,BYTE mData)
{
ui8 tem = hBit - lBit + 1;
tem = (1 << tem) - 1;
mData &= tem; //discard bits may be redundant
*pBYTE &= ~(tem << lBit); //clear specified bits
*pBYTE |= (mData << lBit); //set specified bits
return *pBYTE;
}
//End of SetBits(BYTE* pBYTE,BITPOS hBit,BITPOS lBit,BYTE mData)
//***********************************************************************/
ui8 GetBit(i8 mData,BITPOS pos)
{
return (mData & (1 << pos)) >> pos;
}
//End of GetBit(i8 mData,BITPOS pos)
//***********************************************************************/
ui8 GetBits(i8 mData,BITPOS hBit,BITPOS lBit)
{
ui8 tem = hBit - lBit + 1;
tem = 1 << tem - 1;
return (mData & tem << lBit) >> lBit;
}
//End of GetBits(i8 mData,BITPOS hBit,BITPOS lBit)
2.5 字符串相关的函数定义及实现。字符串是一个以0结尾的ASCII码数组。
2.5.1 函数定义
/string function
/***********************************************************************
Function: UcarBToString(ui8 src,ui8* desString);
Return value: desString
Discription: covert binary places of an unsigned char data binary places to string
Example:
ui8 tem = 123;
ui8 mstr[9] = {0};
UcharBToString(tem,mstr);
***********************************************************************/
ui8* UcharBToString(ui8 src,ui8* desString);
/***********************************************************************
Function: BStringToUchar(ui8 src[],ui8* destData);
Return value
Discription: covert string made of binary character to unsigned char
Example:
ui8 mstr[9] = "10101";
ui8 tem;
BStringToUchar(mstr,&tem);
***********************************************************************/
ui8 BStringToUchar(ui8 src[],ui8* destData);
/***********************************************************************
Function: SubString(ui8* srcString,ui8* desString,ui8 startPos, ui8 size_n);
Return Value: desString(substring)
Discription:cut a string from destination string
Example:
ui8 str1[10] = "123459789";
ui8 mstr2[9] = {0};
SubString(str1,mstr2,2,4); //"3456"
***********************************************************************/
ui8* SubString(ui8* srcString,ui8* desString, ui8 startPos, ui8 size_n);
2.5.2 函数实现
//***********************************************************************/
ui8* UcharBToString(ui8 src,ui8* desString)
{
ui8 i;
memset(desString,0,strlen(desString));
for(i = 0; i < 8; i++)
{
if((src << i)&0x80)
desString[i] = '1';
else
desString[i] = '0';
}
return desString;
}
//End of UcharBToString(ui8 src,ui8* desString)
//***********************************************************************/
ui8 BStringToUchar(ui8 src[],ui8* destData)
{
ui8 len = strlen(src);
ui8 i;
*destData = 0;
for(i = 0; i < len ; i++)
{
*destData <<= 1;
if(src[i]- '0')
*destData += 1;
}
return *destData;
}
//End of BStringToUchar(ui8 src[],ui8* destData)
//***********************************************************************/
ui8* SubString(ui8* srcString,ui8* desString, ui8 startPos, ui8 size_n)
{
ui8 i;
memset(desString,0,strlen(desString));
if(sizeof(srcString)/sizeof(char)> startPos + size_n)
{
for(i = 0; i < size_n; i++)
desString[i] = srcString[startPos + i];
}
return desString;
}
//End of SubString(ui8* srcString,ui8* desString, ui8 startPos, ui8 size_n)