本帖最后由 xiaoqi976633690 于 2022-11-8 17:49 编辑
我用的是keil,没有用官方的图形界面,可能和个人习惯有关
先看下keil的主目录结构:
免按RST一键烧录功能:
使用开发板调试的时候经常要烧录验证,不断的按rst键非常影响效率,于是想着看能不能不按rst键自动进入复位然后自动下载。
代码:
首先我们把rst信号接入到自己选的P02脚,然后初始化
/*****************************************************
*函数名称: SC_GPIO_Init
*函数功能: GPIO初始化函数
*入口参数:void
*出口参数:void
*****************************************************/
void SC_GPIO_Init(void)
{
GPIO_Init(GPIO0, GPIO_PIN_1,GPIO_MODE_OUT_PP);
GPIO_Init(GPIO0, GPIO_PIN_2,GPIO_MODE_OUT_PP);
GPIO_WriteHigh(P0_2);
/*GPIO_Init write here*/
}
一键复位函数:
void auto_FLASH(void)
{
if((RX_BUFF[1]==0x01)||(RX_BUFF[2]==0x00)||(RX_BUFF[3]==0x00))//点击“更新程序”串口RX_BUFF会更新,PC会向单片机串口不断发送68 01 00 00 69 16 数据(请求进入BootLoader)
{
GPIO_WriteLow(P0_2);//接单片机复位脚
}
}
中断函数:
void USCI1Interrupt() interrupt 15
{
if(USCI1_GetFlagStatus(USCI1_UART_FLAG_RI))
{
if(rx_flag>=6) rx_flag=0;
RX_BUFF[rx_flag]=USCI1_UART_ReceiveData8();
rx_flag++;
USCI1_UART_SendData8( USCI1_UART_ReceiveData8());//发送完成置0
while(USCI1_GetFlagStatus(USCI1_UART_FLAG_TI));
USCI1_ClearFlag(USCI1_UART_FLAG_RI);//软件置1
}
USCI1_ClearFlag(USCI1_UART_FLAG_RI);
USCI1_ClearFlag(USCI1_UART_FLAG_TI);
}
ADC获取输入电压:
float get_vdd(void)//获取输入电压值
{
u16 i=0,time_err=0;
u32 adc_value=0;
ADC_VrefConfig(ADC_VREF_2_048V);//设置参考电压
for(i=0;i<10;i++)//采样次数
{
ADC_ChannelConfig(ADC_CHANNEL_VDD_D4,ENABLE);
ADC_StartConversion();
while(!ADC_GetFlagStatus()) //等待 ADC转换完成;
{
time_err++;
if(time_err>=500)
{
ADC_ClearFlag();
break;
}
}
ADC_ClearFlag();
adc_value+=ADC_GetConversionValue();
}
adc_value/=10;
return (adc_value*0.002);//adc_value*2.048/4096*4 可以提前算出已知变量2.048/4096*4=0.002
}
获取任意ADC通道:
u16 adc_get_value(ADC_Channel_TypeDef ADC_Channel)//获取ADC通道值ADC_CHANNEL_0~ADC_CHANNEL_15
{
u16 i=0,time_err=0;
u32 adc_value=0;
ADC_VrefConfig(ADC_VREF_VDD);//设置参考电压
for(i=0;i<10;i++)//采样10次
{
ADC_ChannelConfig(ADC_Channel,ENABLE);
ADC_StartConversion();
while(!ADC_GetFlagStatus()) //等待 ADC转换完成;
{
time_err++;
if(time_err>=500)
{
ADC_ClearFlag();
break;
}
}
ADC_ClearFlag();
adc_value+=ADC_GetConversionValue();
}
return adc_value/10;
}
延时和串口重定向: void delay_10us()
{
/*<UserCodeStart>*//*<SinOne-Tag><47>*/
unsigned char a,b;
for(b=1;b>0;b--)
for(a=157;a>0;a--);
/*<UserCodeEnd>*//*<SinOne-Tag><47>*/
}
////32mhz 延时1ms
void delay_1ms(void)
{
/*<UserCodeStart>*//*<SinOne-Tag><26>*/
u32 i=579;
while(i--);
/*<UserCodeEnd>*//*<SinOne-Tag><26>*/
}
void delay_ms(u32 i)
{
/*<UserCodeStart>*//*<SinOne-Tag><29>*/
while(i--)
{
delay_1ms();
}
/*<UserCodeEnd>*//*<SinOne-Tag><29>*/
}
void sendByte(u8 dat)
{
/*<UserCodeStart>*//*<SinOne-Tag><103>*/
delay_10us();//没有延时会发送失败
delay_10us();
// delay_1ms();
USCI1_UART_SendData8(dat);//发送完成置零
while(USCI1_GetFlagStatus(USCI1_UART_FLAG_TI));
USCI1_ClearFlag(USCI1_UART_FLAG_TI);
// delay_1ms();
/*<UserCodeEnd>*//*<SinOne-Tag><103>*/
}
void sendString(unsigned char *string)
{
/*<UserCodeStart>*//*<SinOne-Tag><105>*/
while(*string!='\0') //指针的数据没到最后一位一直执行循环体
{
sendByte(*string); //发送指针指向的数据(字节byte)
string++; //指针自增,指向下一个数据
}
/*<UserCodeEnd>*//*<SinOne-Tag><105>*/
}
/*
KEIL里扩展出了b,h,l来对输入字节宽的设置:
(1)b八位
(2)h十六位(默认)
(3)l三十二位
注意包含 #include <stdio.h>
在Keil C51中用printf输出一个单字节变量时要使用%bd,如
unsigned char counter;
printf(“Current count: %bd\n”, counter);//输出8位”十进制有符号整数”
printf(“Current count: %bx\n”, counter);//输出8位”无符号以十六进制表示的整数”
*/
char putchar(char c){
sendByte(c);
return c;
}
/*************************************.Generated by EasyCodeCube.************************************/
main函数:
void main(void)
{
unsigned char b=0;
// MCU init
SC_Init();
while(1)
{
GPIO_WriteLow(P0_1);
delay_ms(500);
auto_FLASH();
printf("\r");
printf("%bu,%bu \r",b++,sizeof(b));//%d=short, %bd=char, %ld=long u=unsigned du,bu,lu
printf("AIN0_adc= %d,AIN0_voltage= %.2f \r",adc_get_value(ADC_CHANNEL_0),get_vdd()/4096*adc_get_value(ADC_CHANNEL_0));
printf("VDD= %.2F \r",get_vdd());
GPIO_WriteHigh(P0_1);
delay_ms(500);
}
}
串口打印:
180,1
AIN0_adc= 2639,AIN0_voltage= 3.30
VDD= 5.12
181,1
AIN0_adc= 2637,AIN0_voltage= 3.30
VDD= 5.12
182,1
AIN0_adc= 2639,AIN0_voltage= 3.30
VDD= 5.11
工程源文件:
led_blink.zip
(1.26 MB)
|