重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
是这样的,keil的stdio.h提供了一堆函数,大致分两类,一类是通过串口在上位机上输入输出,另一类是指定一个指针变量,向其输入输出,这样便可以将得到的字符数组指针的内容输出到LCD一类设备上了,也可通过指针获得按键输入。
永安ssl适用于网站、小程序/APP、API接口等需要进行数据传输应用场景,ssl证书未来市场广阔!成为创新互联的ssl证书销售渠道,可以享受市场价格4-6折优惠!如果有意向欢迎电话联系或者加微信:18982081108(备注:SSL证书合作)期待与您的合作!
对于一类,你必须得软件初始化串口,硬件与电脑连接好,然后利用windows的超级终端就可以显示单片机中程序里的printf等函数打印出的内容了,你也可以使用getchar获得超级终端的按键码。(当然也可以使用串口助手之类软件代替超级终端,注意波特率,数据位,校验位,等设置要保持一致)
对于第二类,是不用初始化串口的,因为跟串口没任何关系,你只要用指针虚拟设备就可以了,输入输出都是你自己做的硬件。
附串口初始化程序:
#define T1_INIT_VALUE 0x0D //定时器1初始值设定 9600bps@11.0592MHz
void UartInit(void) {
SCON = 0x50; //8位数据,可变波特率
TMOD = 0x0f; //清除定时器1模式位
TMOD |= 0x20; //设定定时器1为8位自动重装方式
TL1 = T1_INIT_VALUE; //设定定时初值
TH1 = T1_INIT_VALUE; //设定定时器重装值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
ES = 0; //禁止串行口中断
TI = 1; //必须置高TI,RI
RI = 1;
puts("Uart Initialize Success!");
// *.调用printf之前应该关闭串口中断使能
}
printf()是以规定的格式向单片机的串口输出数据 原型如下: extern int printf (const char *, ...);
const char *是格式控制字符串指针,必须以%开始, %[flags][width][.precision]][modified] type
scanf()函数是依规定的格式从串口输入数据,extern int scanf( const char * , ....)
与printf相同其格式控制符需要以%开始,一一个格式字符结束,中间可以插入附加字符:
%[*][width][modifiers]type
c51 汇编调用c函数:一般都是C调用汇编的,倒是反过来了,在C函数中,如果要严格时序或者精确操作的要求,某一段会用汇编来写,不管是C调用汇编,还是汇编调用C。
我的程序KEIL编译器,EXTRN CODE(_Send_CRC)的第一个国家Send_CRC C函数编译加上调用_LCALL _Send_CRC如果您要成相应的数据,然后使用变量在C,XDATA代码。
一般形式:
函数名(实参表列);如果是调用无参函数,则"实参表列"可以没有,但括弧不能省略。如果实参表列包含多个实参,则个参数间用逗号隔开。实参与形参的个数应相等,类型应一致。
实参与形参按顺序对应,一一传递数据。但应说明,如果实参表列包括多个实参,对实参求值的顺序并不是确定的,有的系统按自左至右顺序求实参的值,有的系统则按自右至左顺序
extern void _nop_ (void); //空操作,相当于8051的NOP指令
extern bit _testbit_ (bit); //测试并清零位,相当于8051的JBC指令
extern unsigned char _cror_ (unsigned char, unsigned char); //字符循环右移
extern unsigned int _iror_ (unsigned int, unsigned char); //整数循环右移
extern unsigned long _lror_ (unsigned long, unsigned char); //长整数循环右移
extern unsigned char _crol_ (unsigned char, unsigned char); //字符循环左移
extern unsigned int _irol_ (unsigned int, unsigned char); //整数循环左移
extern unsigned long _lrol_ (unsigned long, unsigned char); //长整数循环左移
extern unsigned char _chkfloat_(float); //测试并返回源点数状态
看你的要求~~
c语言是函数式语言,所以函数很重要,举个例子 #includestdio.h int abc(int a ,int b) /* abc 前的 int 表示这个函数的返回值是整数,abc 是函数名称,括号里的是定义了两个参数它们都是整数*/ { int a=123; printf("%d",a); } 这个是我们自己写的函数,还有现成的c库函数,直接调用就行,限于篇幅,其实你仔细的抠书,书上都有,我就是看书学会的
在你原来的函数基础上,加上三个参数,分别是:
1 要操作的PORT口
2 要进行的操作
3 要操作的引脚
当然,如果你的目标很明确,可以把以上三个参数裁剪掉一些,利于系统的效率提高.
下面是我写的示例程序,你可能参考一下:
#includereg52.h
#define Pin0 0x01
#define Pin1 0x02
#define Pin2 0x04
#define Pin3 0x08
#define Pin4 0x10
#define Pin5 0x20
#define Pin6 0x40
#define Pin7 0x80
#define OPT_CPL 0x00 //----取反某位操作
#define OPT_CLR 0x01 //----清零某位操作
#define OPT_SET 0x02 //----置一某位操作
void Operate(
/*这里写你原来的参数,*/
unsigned char Port_Num,
unsigned char Opr_Style,
unsigned char Pins
)
{
//----如果在单片机PORT口范围之内,刚读取当前PORT口的状
//----如果不在范围之内,死循环
//----注意,为了效率起见,这个部分可以根据实际应用进行裁剪
if(Port_Num == 0)
{
Port_Num = P0;
}
else if(Port_Num == 1)
{
Port_Num = P1;
}
else if(Port_Num == 2)
{
Port_Num = P2;
}
else if(Port_Num == 3)
{
Port_Num = P3;
}
else
{
while(1);
}
//----如果是取反相应位,进行异或操作
//----如果清零相应位,则位与操作
//----如果置位相应位,则位或操作
//----如果都不在范围之内,则死循环
//----这段代码也根据实际情况裁剪
if(Opr_Style == OPT_CPL)
{
Port_Num ^= Pins;
}
else if(Opr_Style == OPT_CLR)
{
Port_Num = ~Pins;
}
else if(Opr_Style == OPT_SET)
{
Port_Num |= Pins;
}
else
{
while(1);
}
//----如果在单片机PORT口范围之内,刚读取当前PORT口的状
//----如果不在范围之内,死循环
//----注意,为了效率起见,这个部分可以根据实际应用进行裁剪
if(Port_Num == 0)
{
P0 = Port_Num;
}
else if(Port_Num == 1)
{
P1 = Port_Num;
}
else if(Port_Num == 2)
{
P2 = Port_Num;
}
else if(Port_Num == 3)
{
P3 = Port_Num;
}
else
{
while(1);
}
//----以上的内容,可根据实际情况进行裁剪,以实现程序最优化
//----添加你的功能的其他代码---------------
}
void main(void)
{
//----使用示例:函数功能的同时,置位P2口的P2.0,P2.5,P2.7
Operate(/*这里写你原来的参数*/2,OPT_SET,(Pin0|Pin5|Pin7));
//----使用示例:函数功能的同时,清零P1口的P1.2,P1.5,P2.6
Operate(/*这里写你原来的参数*/1,OPT_CLR,(Pin2|Pin5|Pin6));
}