- 打卡等级:以坛为家I
- 打卡总天数:283
- 最近打卡:2026-04-02 13:58:02
已绑定手机
金牌会员
- 积分
- 1260
|
#include <stc8h.h>
#include <intrins.h>
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
// 系统时钟和波特率配置
#define MAIN_Fosc 24000000L // 系统钟频率
sbit P3_2 = P3^2;
sbit P3_3 = P3^3;
sbit P3_4 = P3^4;
sbit P3_5 = P3^5;
// 音量控制命令模板 - 除了第13个字节(音量)和第16个字节(校验和)外的固定部分
const u8 CMD_TEMPLATE[14] = {0x01,0x0F,0x1E,0xB0,0x6E,0x02,0x1E,0xA9,0x01,0x01,0x02,0x23,0x00,0x59};
const u8 CMD_SUFFIX[2] = {0xD2, 0x00}; // 固定的倒数第二字节和校验和的偏移量
// 音量值和对应的校验和映射表
const u8 VOLUME_VALUES[21] = {0x01, 0x0E, 0x19, 0x26, 0x32, 0x40, 0x4D, 0x5A, 0x66, 0x73, 0x7F,
0x8C, 0x99, 0xA6, 0xB2, 0xC0, 0xCE, 0xD9, 0xE6, 0xF2, 0x00};
const u8 CHECKSUM_VALUES[21] = {0xD0, 0xDF, 0xC8, 0xF7, 0xE3, 0x91, 0x9C, 0x8B, 0xB7, 0xA2, 0xAE,
0x5D, 0x48, 0x77, 0x63, 0x11, 0x1F, 0x08, 0x37, 0x23, 0xD1};
char sm_1 [] = {0x01,0x0F,0x1E,0xB0,0x6E,0x02,0x1E,0xA9,0x01,0x01,0x02,0x23,0x01,0x59,0xD2,0xD0,};
/**
* 延时函数(毫秒级)
*/
void delay_ms(unsigned int ms)
{
unsigned int i;
do{
i = MAIN_Fosc / 10000;
while(--i);
}while(--ms);
}
// 定时器2相关变量
u16 timer_count = 0;
u8 send_enable = 1; // 发送使能标志
u8 receive_counter = 0; // 接收计数器
/**
* 定时器2初始化函数 (用于100ms定时)
*/
void Timer2_Init(u16 time)
{
AUXR |= 0x04; //定时器时钟1T模式
T2H = (65536 - (MAIN_Fosc / time)) >> 8; // 设置定时器初值,1ms中断
T2L = (65536 - (MAIN_Fosc / time)) & 0xFF;
AUXR |= 0x10; //定时器2开始计时
IE2 = ET2; //使能定时器中断
EA = 1; // 开启总中断
}
/**
* 串口1初始化函数 (用于与电脑通信,P3.0/P3.1)
* 配置: 波特率9600, 无校验, 1位停止位
*/
void UART1_Init(u32 brt)
{
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x40; //定时器时钟1T模式
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //设置定时器模式
TH1 = (u8)((65536UL - (MAIN_Fosc / 4) / brt) >> 8);
TL1 = (u8) 65536UL - (MAIN_Fosc / 4) / brt;
ET1 = 0; // 禁止Timer1中断
TR1 = 1; // 运行Timer1
SCON = (SCON & 0x3f) | (7<<6); // 8位数据, 1位校验位, 1位起始位, 1位停止位
// SCON = 0xD0; // 9位数据, 可变波特率, 1位奇校验, 1位停止位 (模式3)
ES = 1; //允许中断
EA = 1; // 开总中断
P_SW1 &= ~0xc0; //UART1/USART1: RxD(P3.0), TxD(P3.1)
}
/**
* 串口1发送一个字节 (用于发送到电脑)
*/
void UART1_SendByte(unsigned char dat)
{
SBUF = dat; // 写入发送数据
while(!TI); // 等待发送完成(TI=1)
TI = 0; // 清除TI标志位
}
/**
* 发送字符串
*/
void SendString(char *s, int num)
{
while (num--) //检测字符串结束标志
{
UART1_SendByte(*s++); //发送当前字符
}
}
/**
* 发送12个0x55字节
*/
void SendBytes1()
{
u8 i;
for(i = 0; i < 11; i++)
{
UART1_SendByte(0x55);
}
}
void SendBytes2()
{
u8 i;
for(i = 0; i < 11; i++)
{
UART1_SendByte(0x00);
}
}
/**
* 发送指定音量等级的音频控制命令
*/
void SendVolumeCommand(u8 volume_index)
{
u8 command[16]; u8 i;
if(volume_index >= 21) return;
// 构建命令:复制模板 + 音量值 + 固定后缀 + 校验和
for(i = 0; i < 12; i++) {
command[i] = CMD_TEMPLATE[i];
}
command[12] = VOLUME_VALUES[volume_index]; // 音量值
command[13] = CMD_TEMPLATE[13]; // 0x59
command[14] = CMD_SUFFIX[0]; // 0xD2
command[15] = CHECKSUM_VALUES[volume_index]; // 校验和
SendString((char*)command, 16);
}
/**
* 串口1中断服务函数 (接收来自设备的数据)
*/
void Uart1_Isr(void) interrupt 4
{
u8 received_data;
if(RI)
{
RI = 0;
received_data = SBUF; // 读取接收到的数据
// 检查是否接收到0x55
if(received_data == 0x55)
{
receive_counter++;
// 如果连续接收到10个0x55,停止发送
if(receive_counter >= 10)
{
send_enable = 0; // 停止发送
receive_counter = 0; // 重置计数器
}
}
else
{
// 如果不是0x55,重置计数器
receive_counter = 0;
}
// 将接收到的数据回传到电脑
UART1_SendByte(received_data);
}
if(TI)
{
TI = 0;
}
}
/**
* 定时器2中断服务函数
*/
void Timer2_ISR() interrupt 12
{
static u16 ms_count = 0;
timer_count++;
ms_count++;
if(ms_count >= 500 && send_enable) // 100ms且发送使能
{
ms_count = 0;
SendBytes1(); // 发送12个0x55字节
}
}
void main(void)
{
P_SW2 |= 0x80; //扩展寄存器(XFR)访问使能
P0M1 = 0x00; P0M0 = 0x00; //设置为准双向口
P1M1 = 0x00; P1M0 = 0x00;
P2M1 = 0x00; P2M0 = 0x00;
P3M1 = 0x00; P3M0 = 0x00;
P4M1 = 0x00; P4M0 = 0x00;
P5M1 = 0x00; P5M0 = 0x00;
P6M1 = 0x00; P6M0 = 0x00;
P7M1 = 0x00; P7M0 = 0x00;
UART1_Init(9600); // 初始化串口1 (与电脑通信)
Timer2_Init(1000); // 初始化定时器2用于100ms定时
while(1)
{
if(P3_2==0)
{
delay_ms(10);
if(P3_2==0)
{
while(!P3_2);
// SendVolumeCommand(0); // 发送音量等级0(对应0x01)
SendString(sm_1,sizeof(sm_1));
delay_ms(500);
SendBytes2();
P20 = !P20;
}
}
if(P3_3==0)
{
delay_ms(10);
if(P3_3==0)
{
while(!P3_3);
SendVolumeCommand(10); // 发送音量等级10(对应0x7F)
delay_ms(500);
SendBytes2();
P21 = !P21;
}
}
}
}
为什么串口助手发送数据正常 我这个程序发送数据不行
|
-
|