用485进不去串口中断,但是用串口就可以进去。串口调试的话,我发一个指令就会回我一个,但是我用usb转485发送指令,不会回我指令
#include <STC8G.H>
#include "SHT30.h"
#include "uart.h"
#include "delay.h"
#include "Timer0.h"
#include "modbus.h"
int T, H;
unsigned int crc_res;
unsigned char tx_buf[10];
volatile unsigned char RX_flag=0;
volatile unsigned char Time_count=0;
volatile unsigned char RX_count=0;
unsigned char RX_buff[MAX_count];
void main()
{
UartInit(); // 串口初始化
SHT30_Init(); // SHT30引脚初始化
RS485_Init();
Timer0_Init();
EA=1;
Delayms(100);
while(1)
{
SHT30_ReadData(&T, &H);
if (RX_flag)
{
ES=0;//关闭串口中断
// 收到指令后,首先屏蔽定时器判定,防止处理期间被重置
// 校验地址和功能码
if (RX_buff[0] == 0x01 && RX_buff[1] == 0x03)
{
tx_buf[0] = 0x01;
tx_buf[1] = 0x03;
tx_buf[2] = 0x04;
tx_buf[3] = (unsigned char)(T>> 8); // 取高8位
tx_buf[4] = (unsigned char)(T& 0xFF); // 取低8位
tx_buf[5] = (unsigned char)(H >> 8); // 湿度高8位
tx_buf[6] = (unsigned char)(H & 0xFF); // 湿度低8位
crc_res = Modbus_CRC16(tx_buf, 7);
tx_buf[7] = crc_res & 0xFF;
tx_buf[8] = crc_res >> 8;
RS485_Send(tx_buf, 9);
}
Delayms(5);
RX_count = 0;
RX_flag = 0;
ES=1;
}
}
//UartInit(); // 串口初始化
//SHT30_Init(); // SHT30引脚初始化
// Uart_SendString("System Start...\r\n");
// while (1) {
// if (SHT30_ReadData(&T, &H)) {
// // 打印温度
// Uart_PrintResult("Temp: ", T);
// Uart_SendString(" C ");
//
// // 打印湿度
// Uart_PrintResult("Humi: ", H);
// Uart_SendString(" %\r\n");
// } else {
// Uart_SendString("SHT30 Error!\r\n");
// }
// Delayms(1000);; // 每秒测量一次
// }
}
void UART_ISR() interrupt 4
{
if(RI)
{
RI=0;
if(RX_count<MAX_count)
{
RX_buff[RX_count]=SBUF;//接受发过来的数据
RX_count++;
}
Time_count=0;
}
}
void Timer0_ISP() interrupt 1
{
if(RX_count>0)//接收到了数据
{
Time_count++;
if(Time_count>5)//超时
{
RX_flag=1;//接受完成标志位
Time_count=0;
}
}
}
#include "uart.h"
void UartInit(void) //9600bps@11.0592MHz
{
PCON &= 0x7F; //波特率不倍速
SCON = 0x50; //8位数据,可变波特率
AUXR &= 0xBF; //定时器时钟12T模式
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //设置定时器模式
TMOD |= 0x20; //设置定时器模式
TL1 = 0xFD; //设置定时初始值
TH1 = 0xFD; //设置定时重载值
ET1 = 0; //禁止定时器%d中断
TR1 = 1; //定时器1开始计时
ES=1; //打开串口中断
}
// 发送单个字节
void Uart_SendByte(u8 dat) {
SBUF = dat;
while (!TI); // 等待发送完成
TI = 0; // 清除发送标志
}
// 发送字符串
void Uart_SendString(char *s) {
while (*s) {
Uart_SendByte(*s++);
}
}
// 将整数拆分并打印成 x.x 的形式
// 例如:val = 256 -> 打印 "25.6"
void Uart_PrintResult(char *label, int val) {
u8 buf[6];
u8 i = 0;
u8 is_neg = 0;
u8 decimal;
Uart_SendString(label); // 打印标签如 "Temp: "
if (val < 0) {
is_neg = 1;
val = -val;
}
decimal = (u8)(val % 10); // 取小数位
val /= 10; // 取整数部分
// 转换整数部分到字符串
if (val == 0) {
buf[i++] = '0';
} else {
while (val > 0) {
buf[i++] = (val % 10) + '0';
val /= 10;
}
}
if (is_neg) Uart_SendByte('-');
// 倒序打印整数部分
while (i > 0) {
Uart_SendByte(buf[--i]);
}
// 打印小数点和第一位小数
Uart_SendByte('.');
Uart_SendByte(decimal + '0');
}
//串口重定向,用printf打印
char putchar(char c)//必需的写putchar,不能分开写put_char
{
Uart_SendByte(c);
return c;
}
#include "Timer0.h"
void Timer0_Init(void) // 1毫秒@11.0592MHz (STC8G)
{
AUXR &= 0x7F; // 定时器时钟12T模式
TMOD &= 0xF0; // 设置定时器模式
TL0 = 0x71; // 设置定时初始值
TH0 = 0xF9; // 设置定时初始值
TF0 = 0; // 清除TF0标志
TR0 = 1; // 定时器0开始计时
ET0 = 1; // 开启定时器0中断
}
#include "modbus.h"
//modbusCRC校验
unsigned int Modbus_CRC16(unsigned char *buf, unsigned char len)
{
unsigned int crc = 0xFFFF;
unsigned char i, j;
for(i = 0; i < len; i++) {
crc ^= buf[i];
for(j = 0; j < 8; j++) {
if(crc & 0x0001) {
crc >>= 1;
crc ^= 0xA001;
} else {
crc >>= 1;
}
}
}
return crc;
}
void RS485_Init(void)
{
P3M1 &= ~0x08; P3M0 |= 0x08;//P3.3 推挽输出 (RS485控制)
RS485_DIR=0;//接收模式
}
void RS485_Send(unsigned char *p, unsigned char len)
{
RS485_DIR = 1; // 发送模式
while (len--)
{
SBUF = *p++;
while (!TI);
TI = 0;
}
Delayms(2);
RS485_DIR = 0; // 接收模式
}