//注意,如您使用的MCU没有那个功能,就不要 *** 作相应的寄存器
//注意,如您使用的MCU没有那那么大的扩展SRAM,就不要 *** 作超过范围的SRAM
#include<reg51h>
#include<intrinsh>
sfr S2CON = 0x9A;
//S2SM0,S2SM1,S2SM2,S2REN,S2TB8,SRB8,S2TI,S2RI
sfr IE2 = 0xAF;
//X,X,X,X,X,X,ESPI,ES2
sfr S2BUF = 0x9B;
sfr AUXR = 0x8e;
sfr BRT = 0x9c;
sfr IAP_CONTR = 0xC7;
sfr CCON = 0xD8;
sfr CMOD = 0xD9;
sfr CL = 0xE9;
sfr CH = 0xF9;
sfr CCAP0L = 0xEA;
sfr CCAP0H = 0xFA;
sfr CCAPM0 = 0xDA;
sfr CCAPM1 = 0xDB;
sbit CR = 0xDE;
sbit MCU_Start_Led = P1^7;
sbit S2_Interrupt_Receive_Led = P1^4;
//unsigned char self_command_array[4] = {0x22,0x33,0x44,0x55};
#define Self_Define_ISP_Download_Command 0x22
#define RELOAD_COUNT 0xfb //18432MHz,12T,SMOD=0,9600bps
void serial_port_one_initial();
void send_UART_one(unsigned char);
void UART_one_Interrupt_Receive(void);
void serial_port_two_initial();
void send_UART_two(unsigned char);
void UART_two_Interrupt_Receive(void);
void soft_reset_to_ISP_Monitor(void);
void delay(void);
void display_MCU_Start_Led(void);
void send_PWM(void);
void main(void)
{
unsigned int array_point = 0;
unsigned char xdata Test_array_one[512] =
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
0xef, 0xee, 0xed, 0xec, 0xeb, 0xea, 0xe9, 0xe8,
0xe7, 0xe6, 0xe5, 0xe4, 0xe3, 0xe2, 0xe1, 0xe0,
0xdf, 0xde, 0xdd, 0xdc, 0xdb, 0xda, 0xd9, 0xd8,
0xd7, 0xd6, 0xd5, 0xd4, 0xd3, 0xd2, 0xd1, 0xd0,
0xcf, 0xce, 0xcd, 0xcc, 0xcb, 0xca, 0xc9, 0xc8,
0xc7, 0xc6, 0xc5, 0xc4, 0xc3, 0xc2, 0xc1, 0xc0,
0xbf, 0xbe, 0xbd, 0xbc, 0xbb, 0xba, 0xb9, 0xb8,
0xb7, 0xb6, 0xb5, 0xb4, 0xb3, 0xb2, 0xb1, 0xb0,
0xaf, 0xae, 0xad, 0xac, 0xab, 0xaa, 0xa9, 0xa8,
0xa7, 0xa6, 0xa5, 0xa4, 0xa3, 0xa2, 0xa1, 0xa0,
0x9f, 0x9e, 0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98,
0x97, 0x96, 0x95, 0x94, 0x93, 0x92, 0x91, 0x90,
0x8f, 0x8e, 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88,
0x87, 0x86, 0x85, 0x84, 0x83, 0x82, 0x81, 0x80,
0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x7a, 0x79, 0x78,
0x77, 0x76, 0x75, 0x74, 0x73, 0x72, 0x71, 0x70,
0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x69, 0x68,
0x67, 0x66, 0x65, 0x64, 0x63, 0x62, 0x61, 0x60,
0x5f, 0x5e, 0x5d, 0x5c, 0x5b, 0x5a, 0x59, 0x58,
0x57, 0x56, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50,
0x4f, 0x4e, 0x4d, 0x4c, 0x4b, 0x4a, 0x49, 0x48,
0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, 0x40,
0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38,
0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30,
0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28,
0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20,
0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18,
0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0, 0x09, 0x08,
0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00
};
unsigned char i = 0;
serial_port_one_initial(); //串口1初始化
// serial_port_two_initial(); //串口2初始化
display_MCU_Start_Led(); //点亮发光二极管表示单片机开始工作
// send_UART_two(0x55); //串口2发送数据表示单片机串口正常工作
// send_UART_two(0xaa); //串口2发送数据表示单片机串口正常工作
/
for(array_point=0; array_point<512; array_point++)
{
send_UART_two(Test_array_one[array_point]);
}
/
send_UART_one(0x34); //串口1发送数据表示单片机串口正常工作
send_UART_one(0xa7); //串口1发送数据表示单片机串口正常工作
for(array_point=0; array_point<512; array_point++)
{
send_UART_one(Test_array_one[array_point]);
}
// send_PWM(); //6kHz PWM, 50% duty
while(1);
}
void serial_port_one_initial()
{
SCON = 0x50; //0101,0000 8位可变波特率,无奇偶校验位
// TMOD = 0x21; //0011,0001 设置顶时器1为8位自动重装计数器
// TH1 = RELOAD_COUNT; //设置定时器1自动重装数
// TL1 = RELOAD_COUNT;
// TR1 = 1; //开定时器1
BRT = RELOAD_COUNT;
// BRTR = 1, S1BRS = 1, EXTRAM = 1 ENABLE EXTRAM
AUXR = 0x11; // T0x12,T1x12,UART_M0x6,BRTR,S2SMOD,BRTx12,EXTRAM,S1BRS
ES = 1; //允许串口中断
EA = 1; //开总中断
}
void serial_port_two_initial()
{
//sfr SCON = 0x98;
//SM0,SM1,SM2,REN,TB8,RB8,TI,RI
//sfr S2CON = 0x9A;
//S2SM0,S2SM1,S2SM2,S2REN,S2TB8,S2RB8,S2TI,S2RI
//sfr S2BUF = 0x9B;
//sfr IE2 = 0xAF;
//X,X,X,X,X,X,ESPI,ES2
S2CON = 0x50; //0101,0000 8位可变波特率,无奇偶校验位,允许接收
BRT = RELOAD_COUNT;
// BRTR = 1, S1BRS = 1, EXTRAM = 0 ENABLE EXTRAM
AUXR = 0x11; // T0x12,T1x12,UART_M0x6,BRTR,S2SMOD,BRTx12,EXTRAM,S1BRS
// ES = 1; //允许串口1中断
// ES2 = 1
IE2 = 0x01; //允许串口2中断,ES2=1
EA = 1; //开总中断
}
void send_UART_one(unsigned char i)
{
ES = 0; //关串口中断
TI = 0; //清零串口发送完成中断请求标志
SBUF = i;
while(TI ==0); //等待发送完成
TI = 0; //清零串口发送完成中断请求标志
ES = 1; //允许串口中断
}
void send_UART_two(unsigned char i)
{
//sfr SCON = 0x98;
//SM0,SM1,SM2,REN,TB8,RB8,TI,RI
//sfr S2CON = 0x9A;
//S2SM0,S2SM1,S2SM2,S2REN,S2TB8,S2RB8,S2TI,S2RI
//sfr S2BUF = 0x9B;
//sfr IE2 = 0xAF;
//X,X,X,X,X,X,ESPI,ES2
unsigned char temp = 0;
// ES = 0; //关串口1中断
IE2 = 0x00; //关串口2中断,es2=0
// TI = 0; //清零串口1发送完成中断请求标志
S2CON = S2CON & 0xFD; //B'11111101,清零串口2发送完成中断请求标志
// SBUF = i;
S2BUF = i;
// while(TI ==0); //等待发送完成
do
{
temp = S2CON;
temp = temp & 0x02;
}while(temp==0);
// TI = 0; //清零串口发送完成中断请求标志
S2CON = S2CON & 0xFD; //B'11111101,清零串口2发送完成中断请求标志
// ES = 1; //允许串口1中断
// ES2 = 1
IE2 = 0x01; //允许串口2中断,ES2=1
}
void UART_one_Interrupt_Receive(void) interrupt 4
{
unsigned char k = 0;
if(RI==1)
{
RI = 0;
k = SBUF;
if(k==Self_Define_ISP_Download_Command) //是自定义下载命令
{
delay(); //延时1秒就足够了
delay(); //延时1秒就足够了
soft_reset_to_ISP_Monitor(); //软复位到系统ISP监控区
}
send_UART_one(k+1);
}
else
{
TI = 0;
}
}
void UART_two_Interrupt_Receive(void) interrupt 8
{
//sfr SCON = 0x98;
//SM0,SM1,SM2,REN,TB8,RB8,TI,RI
//sfr S2CON = 0x9A;
//S2SM0,S2SM1,S2SM2,S2REN,S2TB8,S2RB8,S2TI,S2RI
//sfr S2BUF = 0x9B;
//sfr IE2 = 0xAF;
//X,X,X,X,X,X,ESPI,ES2
unsigned char k = 0;
k = S2CON ;
k = k & 0x01;
//if(S2RI==1)
if(k==1)
{
//RI = 0;
S2CON = S2CON & 0xFE; //1111,1110
S2_Interrupt_Receive_Led = 0;
k = S2BUF;
if(k==Self_Define_ISP_Download_Command) //是自定义下载命令
{
delay(); //延时1秒就足够了
delay(); //延时1秒就足够了
soft_reset_to_ISP_Monitor(); //软复位到系统ISP监控区
}
send_UART_two(k+1);
}
else
{
//TI = 0;
S2CON = S2CON & 0xFD; //1111,1101
}
}
void soft_reset_to_ISP_Monitor(void)
{
IAP_CONTR = 0x60; //0110,0000 软复位到系统ISP监控区
}
void delay(void)
{
unsigned int j = 0;
unsigned int g = 0;
for(j=0;j<5;j++)
{
for(g=0;g<60000;g++)
{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
}
}
void display_MCU_Start_Led(void)
{
//sbit MCU_Start_Led = P1^7;
unsigned char i = 0;
for(i=0;i<1;i++)
{
MCU_Start_Led = 0; //顶亮MCU开始工作指示灯
delay();
MCU_Start_Led = 1; //熄灭MCU开始工作指示灯
delay();
MCU_Start_Led = 0; //顶亮MCU开始工作指示灯
}
}
void send_PWM(void)
{
CMOD = 0x00; // CIDL - - - - CPS1 CPS0 ECF Setup PCA Timer
// CPS1 CPS0 = 00, Fosc/12 is PCA/PWM clock
// 18432000/12/256 = 6000
CL = 0x00;
CH = 0x00;
CCAP0L = 0x80; //Set the initial value same as CCAP0H
CCAP0H = 0x80; //50% Duty Cycle
CCAPM0 = 0x42; //0100,0010 Setup PCA module 0 in 8BIT PWM, P37
CR = 1; //启动 PCA/PWM 定时器
}
我最近也在弄STC的单片机,看了下代码,觉得以下这段似乎有点问题
for(i=0;i<10;i++)
{
tp=0;
ADC_RES=0;
ADC_RESL=0; //低两位清零
ADC_CONTR|=0x08; //启动AD转换
while(!tp) //判断AD转换是否完成
{
tp=0x10;
tp&=ADC_CONTR;
}
ADC_CONTR&=0xe7;
ad_average_result=ADC_RES;
q=q+ad_average_result;
}
你的意图是想做10次转换,然后取平均值作为最终结果吧, while(!tp) 就是说转换完成后将转换完成标志位清零接着再取出转换后的数,可是转换未完成的话就跳出while直接执行后面的语句了吧,不过这个就是有问题应该也不会导致完全没结果输出,也就是结果有问题的话灯应该也会亮的,还有是否确定模拟信号输入口是否和寄存器设置所选的一致,P1ASF这个寄存器我也找不到说明
#include<reg51h>
#define uchar unsigned char
uchar cnt=0;
bit flag=0;
sbit out=P3^3;
sbit key=P3^5;
void t0isr() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
cnt++;
if(key)cnt=0;
if(cnt>40)flag=1;
}
main()
{
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
TR0=1;
ET0=1;
EA=1;
while(1)
{
if(key==0)
{
if(flag==1)led=~led;
}
}
}
重点不在算法,重点是会AD_init() 和AD_get(channel);
会初始化和启动AD转换并读取转换结果
至于换算是根据自己电路情况确定的,由于计算时采用过多的浮点型变量会占用较多内存,造成内存不足,因此有除法时常采用整形变量进行计算,运算时为了保持尾数不丢失,需把被除数扩大100倍或1000倍,如整数123/100=1,小数部分丢失了,为得到123这个结果,需把123扩大100倍,变成12300,12300/100=1230,然后将小数点向左移2位(缩小100倍),即得123 这就是定(小数)点计算
LedCtrl = LedCtrl & 0xdf大概就是一次选通一个数码管,7f df ef bf每次只有一位是0
//以下代码均是复制引用STC官方案例,还望多多包涵,祝你学习愉快
/------------------------------------------------------------------/
/ --- STC MCU Limited ---------------------------------------------/
/ --- STC89-90xx Series MCU A/D Conversion Demo -------------------/
/ If you want to use the program or the program referenced in the /
/ article, please specify in which data and procedures from STC /
/------------------------------------------------------------------/
#include "reg51h"
#include "intrinsh"
#define FOSC 18432000L
#define BAUD 9600
typedef unsigned char BYTE;
typedef unsigned int WORD;
/Declare SFR associated with the ADC /
sfr ADC_CONTR = 0xC5; //ADC control register
sfr ADC_RES = 0xC6; //ADC high 8-bit result register
sfr ADC_LOW2 = 0xC7; //ADC low 2-bit result register
sfr P1ASF = 0x97; //P1 secondary function control register
/Define ADC operation const for ADC_CONTR/
#define ADC_FLAG 0x10 //ADC complete flag
#define ADC_START 0x08 //ADC start control bit
#define ADC_SPEEDHH 0x00 //89 clocks
#define ADC_SPEEDH 0x20 //178 clocks
#define ADC_SPEEDL 0x40 //356 clocks
#define ADC_SPEEDLL 0x60 //534 clocks
void InitUart();
void InitADC();
void SendData(BYTE dat);
BYTE GetADCResult(BYTE ch);
void Delay(WORD n);
void ShowResult(BYTE ch);
void main()
{
InitUart(); //Init UART, use to show ADC result
InitADC(); //Init ADC sfr
while (1)
{
ShowResult(0); //Show Channel0
ShowResult(1); //Show Channel1
ShowResult(2); //Show Channel2
ShowResult(3); //Show Channel3
ShowResult(4); //Show Channel4
ShowResult(5); //Show Channel5
ShowResult(6); //Show Channel6
ShowResult(7); //Show Channel7
}
}
/----------------------------
Send ADC result to UART
----------------------------/
void ShowResult(BYTE ch)
{
SendData(ch); //Show Channel NO
SendData(GetADCResult(ch)); //Show ADC high 8-bit result
//if you want show 10-bit result, uncomment next line
// SendData(ADC_LOW2); //Show ADC low 2-bit result
}
/----------------------------
Get ADC result
----------------------------/
BYTE GetADCResult(BYTE ch)
{
ADC_CONTR = ADC_SPEEDLL | ch | ADC_START;
_nop_(); //Must wait before inquiry
_nop_();
_nop_();
_nop_();
while (!(ADC_CONTR & ADC_FLAG));//Wait complete flag
ADC_CONTR &= ~ADC_FLAG; //Close ADC
return ADC_RES; //Return ADC result
}
/----------------------------
Initial UART
----------------------------/
void InitUart()
{
SCON = 0x5a; //8 bit data ,no parity bit
TMOD = 0x20; //T1 as 8-bit auto reload
TH1 = TL1 = -(FOSC/12/32/BAUD); //Set Uart baudrate
TR1 = 1; //T1 start running
}
/----------------------------
Initial ADC sfr
----------------------------/
void InitADC()
{
P1ASF = 0xff; //Open 8 channels ADC function
ADC_RES = 0; //Clear previous result
ADC_CONTR = ADC_SPEEDLL;
Delay(2); //ADC power-on and delay
}
/----------------------------
Send one byte data to PC
Input: dat (UART data)
Output:-
----------------------------/
void SendData(BYTE dat)
{
while (!TI); //Wait for the previous data is sent
TI = 0; //Clear TI flag
SBUF = dat; //Send current data
}
/----------------------------
Software delay function
----------------------------/
void Delay(WORD n)
{
WORD x;
while (n--)
{
x = 5000;
while (x--);
}
}
端口自己定义啊,首先你用的是P3,STC的需要对P3口的地址先声明,这个51的头文件是没有的,然后定义P3的输出方式为普通IO口。要不然不出结果的,另外你的外电路接的是P35按键是下降沿还是上升沿有效。做的方法很多,定时器,查询都可以的。这个具体算时间要结合你的晶振频率和分频情况(要仔细看手册)
算法不难的,假定按键是低电平有效,也就是if来判断P35管脚是否为0,然后短暂延迟10ms,再次判断P35是否为0,两次结果一直表示触发了一次按键(防抖动)。变量+1
判断1秒内变量是否=2,是=2的话,那么就输出P33有效咯
STC15是一种常用的单片机,其程序设计需要结合具体的开发板和任务需求来确定。一般来说,要快速写出STC15的程序,可以按照以下步骤进行:
1 确定任务需求。首先要明确需要实现什么功能,例如控制电机、采集温度、检测红外等。
2 编写程序框架。根据任务需求,编写程序的基本框架,包括初始化、配置、中断处理和主程序等。
3 编写功能模块。根据任务需求,编写相应的功能模块,例如驱动电机的模块、采集温度的模块、检测红外的模块等。
4 调试程序。在编写完程序后,需要进行调试,确保程序能够正常运行,并且满足任务需求。
5 优化程序。在程序调试完成后,可以进行程序的优化,包括提高程序的运行效率、减少程序的代码长度等。
需要注意的是,STC15的程序设计需要具备一定的单片机开发经验和相关知识,如果您是初学者,可能需要花费一定的时间和精力来学习和掌握相关知识。另外,STC15的程序设计也需要根据具体的实际情况来确定,不同的任务需求和开发板可能需要不同的程序设计方法。
为了保证您获得最佳体验,请前往 >
#include<reg52h>
sbit LED1 = P1^1; //LED1
sbit LED2 = P2^1; //LED2
sbit Key1 = P3^6; //按键
unsigned char Flag = 0; //标志
/
延时1MS子函数
/
void Delay_1ms(unsigned int Time)
{
unsigned int x,y;
for(x = Time; x > 0; x--)
for(y = 120; y > 0; y--);
}
/
按键子函数
/
void Key_Scong(void)
{
if(Key1 == 0) //判断按键按下
{
Delay_1ms(10); //延时去抖动
if(Key1 == 0) //确定按键按下
{
Flag = 1; //标志直位
}
while(Key1 == 0); //等待按键松手
}
}
/
主函数
/
int main(void)
{
while(1)
{
Key_Scong();
if(Flag == 1) //判断标志直位后
{
LED1 = 1; //P10 = 1;
Delay_1ms(1000); //延时1s
Delay_1ms(1000); //延时1s
LED2 = 1;
Delay_1ms(1000);
Delay_1ms(1000);
LED1 = 1;
LED2 = 1;
Delay_1ms(1000);
Delay_1ms(1000);
LED1 = 0;
LED2 = 0;
Flag = 0; //关闭标志
}
else
{
LED1 = 0;
LED2 = 0;
}
}
}
以上就是关于STC单片机串口程序全部的内容,包括:STC单片机串口程序、求解STC 12C5A60S2的编程问题,本人初次涉及单片机,对编程不太了解,编了个AD转化的小程序,求高手看下!、求一个简单的单片机程序,stc15f104e 单片机3.3为输出,3.5接按键,第一次等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)