stc15单片机 固定翼无人机 飞控程序
硬件
- stcf2k60s2
- 2.4g无线通信模块nrf24l01
- mg90s数字舵机
- 摇杆
- 无刷电机
- 电调
用到的单片机资源
- pwm
- ad转换
程序结构
- 利用ADC转换读取摇杆值
- 将摇杆数值转换为16进制通过2.4G无线通信模块发送置接收端
- 通过接收到的数据控制pwm改变来控制舵机电机
硬件使用
-
舵机
采用50Hz的PWM信号控制
-
电调
采用71.4hz的PWM信号控制,高电平宽度为1.0到2.0ms,电调上电需要自检,自检的方法就是给高电平宽度为1ms持续3s左右,当电机发出急促的哔哔哔声音就自己成功,可以开始控制
程序
遥控端
左边摇杆控制油门
右边摇杆控制转向及高度
#include "STC15F2K60S2.H"
#include "stdio.h"
#include "intrins.h"
#include "nrf_24l01.h"
#define uint unsigned int
#define uchar unsigned char
#define ADC_POWER 0xE0
#define ADC_FLAG 0x10
#define ADC_START 0x08
#define ADC_SPEEDLL 0x00
uchar rx_buf[TX_PLOAD_WIDTH];
uchar tx_buf[TX_PLOAD_WIDTH];
unsigned char sta;
uchar dat0;
uchar dat1;
uchar dat2;
uint num;
uint num0;
uint num1;
uint num2;
uint k;
sbit S1=P2^3;
sbit S2=P2^4;
void Delay100ms(void);
void delayms(int ms);
void uartInit(void);
void UARTSend(char ucData);
void UART_PutString(unsigned char *s);
uchar GetADCResult(unsigned char ch);
void InitADC();
void main(void)
{
unsigned int lock_key=0;
P0M0=0X00;P0M1=0X00;
P1M0=0X00;P1M1=0X00;
P2M0=0X00;P2M1=0X00;
P3M0=0X00;P3M1=0X00;
P4M0=0X00;P4M1=0X00;
uartInit();
Delay100ms();
init_nrf24l01_io();
InitADC();
UART_PutString("READY!\r\n");
ifnnrf_rx_mode();
while(1)
{
if(S1==0)
{
delayms(1);
if(S1!=0)
{
k=1;
}
}
if(S2==0)
{
delayms(1);
if(S2!=0)
{
k=2;
}
}
num=GetADCResult(0);
num0=num/51;
num=GetADCResult(2);
if(num<190)
{
num1=num/85;
}
if(190<num&&num<210)num1=3;
if(num>210)
{
num1=(num-210)/15+3;
}
num=GetADCResult(3);
if(num<160)
{
num2=num/80;
}
if(160<num&&num<185)num2=3;
if(num>185)
{
num2=(num-185)/23+3;
}
IRQ=1;
SPI_RW_Reg(WRITE_REG+STATUS,0xff);
tx_buf[0]=num0;
tx_buf[1]=num1;
tx_buf[2]=num2;
ifnnrf_tx_mode();
while(IRQ);
sta=SPI_Read(STATUS);
SPI_RW_Reg(WRITE_REG+STATUS,0xff);
if(sta&STA_MARK_TX)
{
delayms(1);
}
else
{
ifnnrf_CLERN_ALL();
}
lock_key=1;
}
if(lock_key)
{
lock_key=0;
ifnnrf_rx_mode();
IRQ=1;
while(IRQ==0);
_delay_us(400);
}
}
void uartInit(void)
{
SCON = 0x50;
AUXR |= 0x40;
AUXR &= 0xFE;
TMOD &= 0x0F;
TL1 = 0xE0;
TH1 = 0xFE;
ET1 = 0;
TR1 = 1;
EA = 1;
ES=1;
}
void UARTSend(char ucData)
{
SBUF=ucData;
while(TI==0);
TI=0;
}
void UART_PutString(unsigned char *pS)
{
while(*pS)
UARTSend(*pS++);
}
void delayms(int ms)
{
int i,j;
for(i=ms;i>0;i--)
for(j=845;j>0;j--);
}
void Delay100ms(void)
{
unsigned char i, j, k;
_nop_();
_nop_();
i = 5;
j = 52;
k = 195;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
uchar GetADCResult(unsigned char ch)
{
ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START;
_nop_();
_nop_();
_nop_();
_nop_();
while (!(ADC_CONTR & ADC_FLAG));
ADC_CONTR &= ~ADC_FLAG;
return ADC_RES;
}
void InitADC()
{
P1ASF = 0x80;
ADC_RES = 0;
ADC_CONTR = ADC_POWER | ADC_SPEEDLL;
delayms(1);
}
接收端
#include "STC15F2K60S2.H"
#include "intrins.h"
#include "nrf_24l01.h"
uchar rx_buf[TX_PLOAD_WIDTH];
uchar tx_buf[TX_PLOAD_WIDTH];
unsigned char sta;
void Delay100ms(void);
void delayms(int ms);
void uartInit(void);
void UARTSend(char ucData);
void UART_PutString(unsigned char *s);
void Timer0_init(void);
unsigned int ZKB1=0;
unsigned int ZKB2=0;
unsigned int ZKB3=0;
int zhuanxian=0;
int shenjiang=0;
int flag_1=11;
int flag_2=11;
int flag_3=11;
void main(void)
{
while(1)
{
unsigned int lock_key=0;
P0M0=0X00;P0M1=0X00;
P1M0=0X00;P1M1=0X00;
P2M0=0X00;P2M1=0X00;
P3M0=0X00;P3M1=0X00;
P4M0=0X00;P4M1=0X00;
uartInit();
Timer0_init();
Delay100ms();
init_nrf24l01_io();
ifnnrf_rx_mode();
ACC=AUXR1;
ACC&=0xcf;
ACC|=0x10;
AUXR1=ACC;
CCON = 0;
CL = 0;
CH = 0;
CMOD = 0x04;
PCA_PWM0 = 0x00;
CCAP0H = CCAP0L = 256-(256*ZKB1/100);
CCAPM0 = 0x42;
PCA_PWM1 = 0x00;
CCAP1H = CCAP1L = 256-(256*ZKB2/100);
CCAPM1 = 0x42;
PCA_PWM2 = 0x00;
CCAP2H = CCAP2L = 256-(256*ZKB3/100);
CCAPM2 = 0x42;
CR = 1;
IRQ=1;
if(IRQ==0)
{
sta=SPI_Read(STATUS);
SPI_RW_Reg(WRITE_REG+STATUS,0xff);
if(sta&STA_MARK_RX)
{
SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);
if(rx_buf[0] == 0x00&&flag_1!=0)
{
UART_PutString("油门关闭\r\n");
ZKB1=5;
flag_1=0;
}
if(rx_buf[0] == 0x01&&flag_1!=1)
{
UART_PutString("油门1\r\n");
ZKB1=6;
flag_1=1;
}
if(rx_buf[0] == 0x02&&flag_1!=2)
{
UART_PutString("油门2\r\n");
ZKB1=7;
flag_1=2;
}
if(rx_buf[0] == 0x03&&flag_1!=3)
{
UART_PutString("油门3\r\n");
ZKB1=8;
flag_1=3;
}
if(rx_buf[0] == 0x04 &&flag_1!=4)
{
UART_PutString("油门4\r\n");
ZKB1=9;
flag_1=4;
}
if(rx_buf[0] == 0x05&&flag_1!=5)
{
UART_PutString("油门5\r\n");
ZKB1=10;
flag_1=5;
}
if(rx_buf[1] == 0x00&&flag_2!=0&&shenjiang==0)
{
UART_PutString("左转3\r\n");
ZKB2=4;
zhuanxian=1;
flag_2=0;
}
if(rx_buf[1] == 0x01&&flag_2!=1&&shenjiang==0)
{
UART_PutString("左转2\r\n");
ZKB2=5;
zhuanxian=1;
flag_2=1;
}
if(rx_buf[1] == 0x02&&flag_2!=2&&shenjiang==0)
{
UART_PutString("左转1\r\n");
ZKB2=6;
zhuanxian=1;
flag_2=2;
}
if(rx_buf[1] == 0x03&&flag_2!=3&&shenjiang==0)
{
UART_PutString("转向归中\r\n");
ZKB2=7;
ZKB3=7;
zhuanxian=0;
flag_2=3;
}
if(rx_buf[1] == 0x04&&flag_2!=4&&shenjiang==0)
{
UART_PutString("右转1\r\n");
ZKB3=6;
zhuanxian=1;
flag_2=4;
}
if(rx_buf[1] == 0x05&&flag_2!=5&&shenjiang==0)
{
UART_PutString("右转2\r\n");
ZKB3=5;
zhuanxian=1;
flag_2=5;
}
if(rx_buf[1] == 0x06&&flag_2!=6&&shenjiang==0)
{
UART_PutString("右转3\r\n");
ZKB3=4;
zhuanxian=1;
flag_2=6;
}
if(rx_buf[2] == 0x00&&flag_3!=0&&zhuanxian==0)
{
UART_PutString("下降3\r\n");
ZKB2=10;
ZKB3=10;
shenjiang=1;
flag_3=0;
}
if(rx_buf[2] == 0x01&&flag_3!=1&&zhuanxian==0)
{
UART_PutString("下降2\r\n");
ZKB2=9.5;
ZKB3=9.5;
shenjiang=1;
flag_3=1;
}
if(rx_buf[2] == 0x02&&flag_3!=2&&zhuanxian==0)
{
UART_PutString("下降1\r\n");
ZKB2=9;
ZKB3=9;
shenjiang=1;
flag_3=2;
}
if(rx_buf[2] == 0x03&&flag_3!=3&&zhuanxian==0)
{
UART_PutString("上下归中\r\n");
ZKB2=7;
ZKB3=7;
shenjiang=0;
flag_3=3;
}
if(rx_buf[2] == 0x04&&flag_3!=4&&zhuanxian==0)
{
UART_PutString("上1\r\n");
ZKB2=6;
ZKB3=6;
shenjiang=1;
flag_3=4;
}
if(rx_buf[2] == 0x05&&flag_3!=5&&zhuanxian==0)
{
UART_PutString("上2\r\n");
ZKB2=5;
ZKB3=5;
shenjiang=1;
flag_3=5;
}
if(rx_buf[2] == 0x06&&flag_3!=6&&zhuanxian==0)
{
UART_PutString("上3\r\n");
ZKB2=4;
ZKB3=4;
shenjiang=1;
flag_3=6;
}
rx_buf[0] = 0;
rx_buf[1] = 0;
rx_buf[2] = 0;
}
else
{
ifnnrf_CLERN_ALL();
ifnnrf_rx_mode();
IRQ=1;
while(IRQ==0);
}
}
}
}
void uartInit(void)
{
SCON = 0x50;
AUXR |= 0x40;
AUXR &= 0xFE;
TMOD &= 0x0F;
TL1 = 0xE0;
TH1 = 0xFE;
ET1 = 0;
TR1 = 1;
EA = 1;
ES=1;
}
void UARTSend(char ucData)
{
SBUF=ucData;
while(TI==0);
TI=0;
}
void UART_PutString(unsigned char *pS)
{
while(*pS)
UARTSend(*pS++);
}
void delayms(int ms)
{
int i,j;
for(i=ms;i>0;i--)
for(j=845;j>0;j--);
}
void Delay100ms(void)
{
unsigned char i, j, k;
_nop_();
_nop_();
i = 5;
j = 52;
k = 195;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
NRF_24L01.c
SPI通讯采用软件模拟引脚可随意更改
#include "STC15F2K60S2.H"
#include "NRF_24L01.h"
uchar const TX_ADDRESS[TX_ADR_WIDTH] = {0x21,0x43,0x01,0x10,0x01};
extern unsigned char tx_buf[];
extern unsigned char rx_buf[];
extern unsigned char sta;
void _delay_us(unsigned int _us)
{
char a=0;
for(_us;_us;_us--)
for(a=0;a<1;a++);
}
void init_nrf24l01_io(void)
{
CE=0;
CSN=1;
SCK=0;
}
bdata unsigned char st=0;
sbit st_1=st^0;
sbit st_2=st^1;
sbit st_3=st^2;
sbit st_4=st^3;
sbit st_5=st^4;
sbit st_6=st^5;
sbit st_7=st^6;
sbit st_8=st^7;
bdata unsigned char st1=0;
sbit st_11=st1^0;
sbit st_12=st1^1;
sbit st_13=st1^2;
sbit st_14=st1^3;
sbit st_15=st1^4;
sbit st_16=st1^5;
sbit st_17=st1^6;
sbit st_18=st1^7;
uchar SPI_RW(uchar byte)
{
st=byte;
MOSI=st_8;
SCK = 1;
st_18=MISO;
SCK = 0;
MOSI=st_7;
SCK = 1;
st_17=MISO;
SCK = 0;
MOSI=st_6;
SCK = 1;
st_16=MISO;
SCK = 0;
MOSI=st_5;
SCK = 1;
st_15=MISO;
SCK = 0;
MOSI=st_4;
SCK = 1;
st_14=MISO;
SCK = 0;
MOSI=st_3;
SCK = 1;
st_13=MISO;
SCK = 0;
MOSI=st_2;
SCK = 1;
st_12=MISO;
SCK = 0;
MOSI=st_1;
SCK = 1;
st_11=MISO;
SCK = 0;
return(st1);
}
void SPI_RW_Reg(BYTE reg, BYTE value)
{
CSN = 0;
SPI_RW(reg);
SPI_RW(value);
CSN = 1;
}
BYTE SPI_Read(BYTE reg)
{
BYTE reg_val;
CSN = 0;
SPI_RW(reg);
reg_val = SPI_RW(0);
CSN = 1;
return(reg_val);
}
void SPI_Read_Buf(BYTE reg, BYTE *pBuf, BYTE bytes)
{
uchar byte_ctr;
CSN = 0;
SPI_RW(reg);
for(byte_ctr=0;byte_ctr<bytes;byte_ctr++)
pBuf[byte_ctr] = SPI_RW(0);
CSN = 1;
}
void SPI_Write_Buf(BYTE reg, BYTE *pBuf, BYTE bytes)
{
uchar byte_ctr;
CSN = 0;
SPI_RW(reg);
for(byte_ctr=0; byte_ctr<bytes; byte_ctr++)
SPI_RW(*pBuf++);
CSN = 1;
}
void ifnnrf_rx_mode(void)
{
CE=0;
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH);
SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);
SPI_RW_Reg(WRITE_REG + RF_CH, 40);
SPI_RW_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH);
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x27);
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);
CE = 1;
}
void ifnnrf_tx_mode(void)
{
CE=0;
SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH);
SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH);
SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);
SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a);
SPI_RW_Reg(WRITE_REG + RF_CH, 40);
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x27);
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);
CE=1;
}
void SPI_CLR_Reg(BYTE R_T)
{
CSN = 0;
if(R_T==1)
SPI_RW(FLUSH_TX);
else
SPI_RW(FLUSH_RX);
CSN = 1;
}
void ifnnrf_CLERN_ALL()
{
SPI_CLR_Reg(0);
SPI_CLR_Reg(1);
SPI_RW_Reg(WRITE_REG+STATUS,0xff);
IRQ=1;
}
NRF_24L01.h
#ifndef _NRF24L01_
#define _NRF24L01_
#define IRQ P22
#define CE P36
#define CSN P55
#define SCK P41
#define MOSI P37
#define MISO P45
typedef unsigned char uchar;
typedef unsigned char BYTE;
#define TX_ADR_WIDTH 5
#define TX_PLOAD_WIDTH 32
#define READ_REG 0x00
#define WRITE_REG 0x20
#define RD_RX_PLOAD 0x61
#define WR_TX_PLOAD 0xA0
#define FLUSH_TX 0xE1
#define FLUSH_RX 0xE2
#define REUSE_TX_PL 0xE3
#define NOP 0xFF
#define CONFIG 0x00
#define EN_AA 0x01
#define EN_RXADDR 0x02
#define SETUP_AW 0x03
#define SETUP_RETR 0x04
#define RF_CH 0x05
#define RF_SETUP 0x06
#define STATUS 0x07
#define OBSERVE_TX 0x08
#define CD 0x09
#define RX_ADDR_P0 0x0A
#define RX_ADDR_P1 0x0B
#define RX_ADDR_P2 0x0C
#define RX_ADDR_P3 0x0D
#define RX_ADDR_P4 0x0E
#define RX_ADDR_P5 0x0F
#define TX_ADDR 0x10
#define RX_PW_P0 0x11
#define RX_PW_P1 0x12
#define RX_PW_P2 0x13
#define RX_PW_P3 0x14
#define RX_PW_P4 0x15
#define RX_PW_P5 0x16
#define FIFO_STATUS 0x17
#define STA_MARK_RX 0X40
#define STA_MARK_TX 0X20
#define STA_MARK_MX 0X10
void NRF24L01_SPI_Init(BYTE Mode);
uchar SPI_RW(BYTE byte);
uchar SPI_Read(BYTE reg);
void SPI_RW_Reg(BYTE reg, BYTE byte);
void SPI_Write_Buf(BYTE reg, BYTE *pBuf, BYTE bytes);
void SPI_Read_Buf(BYTE reg, BYTE *pBuf, BYTE bytes);
void init_nrf24l01_io(void);
void ifnnrf_rx_mode(void);
void ifnnrf_tx_mode(void);
void ifnnrf_CLERN_ALL();
void _delay_us(unsigned int _us);
#endif
![
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)