如何引用另外一个文件中的串, 顺便说说void print();和(void)print();的区别

     由于需要, 所以小写一下。


     main.cpp中的代码为:

#include <iostream>
using namespace std;

extern char str[];
int main()
{
	cout << str << endl;
	return 0;
}

     test.cpp中的代码为:

char str[100] = "abcdefg";

     程序的结果为:abcdefg



     下一道菜:

     main.cpp

#include <iostream>
using namespace std;
void print();

extern char str[];
int main()
{
	cout << str << endl;
	// cout << sizeof(str) << endl;  //编译错误
	cout << strlen(str) << endl; // 7

	strcpy(str, "xyz");
	cout << str << endl;

	print(); // 输出hello world, xyz,  可见, 上面的strcpy改变了test.cpp中的值
	return 0;
}


    test.cpp

#include <stdio.h>
char str[100] = "abcdefg";

void print()
{
	printf("hello world, %s\n", str);
}


      输出结果:

abcdefg
7
xyz
hello world, xyz


     

       最后看一下void print();和(void)print();的区别:


       void print();是生命, 而(void)print();是调用, 在代码中非常常见, 为什么要加(void)呢, 多数为了通过静态检查工具的检查。


     

<think>根据用户的问题,他希望在操作系统中实现口发送函数void print(unsigned char dat),并知道如何正确调用它。用户已经定义了函数原型,现在需要了解如何实现这个函数以及如何调用。 结合引用中的代码,我们可以从以下几个方面来回答: 1. 口初始化:在调用print函数之前,必须先初始化口(如引用[1][3][4]所示)。 2. 口发送函数实现:print函数内部需要实现数据发送,通常通过写入SBUF寄存器并等待TI标志位完成。 3. 调用方式:直接传递一个字符参数调用print函数。 注意:用户提到是在操作系统中实现,因此需要考虑操作系统的环境(如是否有任务调度、中断等),但用户没有具体说明操作系统细节,我们假设是类似RTOS的环境,但问题中给出的代码片段是裸机程序。因此,这里我们以裸机程序为例,因为大多数嵌入式操作系统的口驱动也是基于类似的原理。 实现步骤: 1. 口初始化函数(参考引用[1][3][4]): - 设置口工作模式(通常模式1,8位数据,可变波特率) - 设置波特率发生器(定时器1或定时器2) - 启动定时器 - 开启口中断(如果使用中断方式,但发送函数也可以使用查询方式) 2. print函数实现(查询方式): ```c void print(unsigned char dat) { SBUF = dat; // 将数据写入发送缓冲器 while (!TI); // 等待发送完成(TI会由硬件置1) TI = 0; // 清除发送中断标志 } ``` 3. 调用示例: ```c void main() { UartInit(); // 初始化print('A'); // 发送字符'A' print('B'); // 发送字符'B' // ... } ``` 注意:如果需要在操作系统中使用,需要注意: - 在RTOS中,如果多个任务同时调用print函数,需要互斥保护(如使用信号量)。 - 也可以使用中断方式发送,但需要建立发送缓冲区(如环形队列),然后在中断服务函数中发送。 根据引用[4],STC15系列单片机使用定时器2作为波特率发生器的初始化方法,我们可以参考其初始化函数。 下面给出一个完整的示例(基于STC15系列,使用定时器2,模式1): ```c #include <STC15F2K60S2.H> #include "intrins.h" // 口初始化函数 void UartInit(void) { SCON = 0x50; // 8位数据,可变波特率 AUXR |= 0x01; // 口1选择定时器2为波特率发生器 AUXR |= 0x04; // 定时器2时钟为Fosc,即1T T2L = 0xE0; // 设定定时初值(11.0592MHz, 9600bps) T2H = 0xFE; // 设定定时初值 AUXR |= 0x10; // 启动定时器2 } // 口发送函数 void print(unsigned char dat) { SBUF = dat; // 发送数据 while (!TI); // 等待发送完成 TI = 0; // 清除发送完成标志 } void main() { UartInit(); // 初始化口 while (1) { print('H'); print('i'); print('\r'); print('\n'); // 延时 // ... 这里可以加上延时函数 } } ``` 注意事项: 1. 波特率计算:根据晶振频率计算定时器初值。例如,11.0592MHz晶振,9600波特率,定时器2的初值计算为: $$ T_{reload} = 65536 - \frac{F_{osc}}{32 \times Baud} $$ $$ T_{reload} = 65536 - \frac{11059200}{32 \times 9600} = 65536 - 36 = 65500 = 0xFFDC $$ 但实际在引用[4]中使用了0xFE0xE0(即T2H=0xFE, T2L=0xE0,组合为0xFEE0=65248),这个值需要根据实际晶振调整。 2. 如果使用其他定时器(如定时器1),初始化方式不同(参考引用[1][3])。 3. 在操作系统中,如果多个任务调用print函数,需要加锁保护,防止多个任务同时发送导致数据错乱。例如: ```c void os_print(unsigned char dat) { os_enter_critical(); // 进入临界区(或获取信号量) print(dat); os_exit_critical(); // 退出临界区(或释放信号量) } ``` 相关问题: 1. 如何计算不同晶振频率下的波特率定时器初值? 2. 在RTOS中如何安全地实现多任务口打印? 3. 如何实现printf函数格式化输出?</think>### 在操作系统中调用口发送函数 `void print(unsigned char dat)` 在操作系统中调用口发送函数需要完成以下步骤,我将结合引用中的关键代码为您详细说明: #### 1. **口初始化(必要前提)** 在调用 `print()` 函数前,必须先初始化口硬件。参考引用[1][3][4]中的初始化方法: ```c void UartInit(void) { SCON = 0x50; // 8位数据模式,允许接收[^1][^3] AUXR |= 0x01; // 使用定时器2作为波特率发生器[^4] AUXR |= 0x04; // 定时器2时钟为Fosc (1T模式)[^4] T2L = 0xE0; // 波特率9600的初值[^4] T2H = 0xFE; AUXR |= 0x10; // 启动定时器2[^4] ES = 1; // 允许口中断[^1] EA = 1; // 开启总中断[^1] } ``` #### 2. **实现 `print()` 函数** 根据引用[1][3][4]中的发送逻辑,实现发送函数: ```c void print(unsigned char dat) { SBUF = dat; // 将数据写入发送缓冲区 while (!TI); // 等待发送完成(TI=1) TI = 0; // 清除发送完成标志 } ``` #### 3. **在操作系统中调用** 在任务或主循环中直接调用,注意避免多任务冲突: ```c void main_task(void) { UartInit(); // 初始化口 while(1) { print('H'); // 发送字符 print('i'); print('!'); print('\r'); // 回车 print('\n'); // 换行 OS_Delay(1000); // 操作系统延时1秒 } } ``` #### 4. **多任务环境注意事项** 在RTOS中需要添加互斥保护: ```c // 定义互斥信号量 OS_MUTEX uart_mutex; void safe_print(unsigned char dat) { OS_MutexWait(&uart_mutex, OS_INFINITE); // 获取互斥锁 SBUF = dat; while (!TI); TI = 0; OS_MutexRelease(&uart_mutex); // 释放互斥锁 } ``` ### 关键实现原理 1. **数据发送流程**: ```mermaid graph LR A[调用print(dat)] --> B[写入SBUF寄存器] B --> C{等待TI标志} C -->|TI=0| C C -->|TI=1| D[清除TI标志] D --> E[发送完成] ``` 2. **波特率计算**: 定时器初值计算公式: $$ T_{initial} = 65536 - \frac{F_{osc}}{32 \times BaudRate} $$ 例如24MHz晶振、9600波特率: $$ T_{initial} = 65536 - \frac{24 \times 10^6}{32 \times 9600} = 65536 - 78.125 \approx 65458 = 0xFFB2 $$ 3. **寄存器作用**: - `SCON`:口控制寄存器 - `SBUF`:发送/接收数据缓冲器 - `TI`:发送中断标志(硬件置1,软件清零) - `AUXR`:辅助寄存器(STC单片机特有) ### 常见问题解决方案 1. **发送卡在 `while(!TI)`**: - 检查波特率设置是否匹配 - 确认定时器是否启动 - 验证晶振频率配置 2. **多任务数据混乱**: ```c // 解决方案:添加互斥锁 OS_MutexWait(&uart_mutex); print("Task1: Hello"); OS_MutexRelease(&uart_mutex); ``` 3. **提高发送效率**: ```c void print_str(char *str) { while (*str) { print(*str++); // 循环发送字符 } } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值