智能车入门补充篇——逐飞开源库介绍

目录

STC16F开源库简介

 底层驱动功能模块

常用外设模块的底层适配

 关键位置

调用模块

应用举例 

系列文章目录

速通版

全程引导篇

详细讲解篇


参考文章地址:逐飞科技STC16F开源库来啦

STC16F开源库简介

STC16F开源库继续沿用逐飞其他开源库的代码风格,使用过逐飞库的同学应该知道,逐飞库的特点是简洁易懂,容易上手。本次STC16F开源库使用MDK FOR C251进行编写。虽然说MDK FOR C251这个版本的IDE听着很陌生,但它还是属于MDK,所以IDE上手还是很容易的。开源库使用单片机寄存器作为最底层。然后将各个模块使用的寄存器进行二次封装,提升易用性。如果有同学有更多需求,发现库的现有功能不满足自己使用需求时,可以采用同样的方式自己调用寄存器来实现所需要的功能。大家可以通过我们的库来学习寄存器怎么使用,当自己学会怎么使用官方的寄存器之后也可以直接使用寄存器,这样的好处就是没有多余的代码,降低自己代码的体积,提高效率。我们也并不希望用户只会用我们的库来做开发,制作开源库的目的是希望初学者不被门槛给拦在外面,提供一个入门学习的渠道。

 首先来看一看STC16F开源库的目录结构图:

Libraries文件夹下放置的是STC头文件,以及数据类型声明,board等文件。

seekfree_libraries文件夹下放置的是逐飞科技精心编写的底层驱动,底层驱动是用STC提供的头文件进行二次封装,以简化各个模块的使用步骤,使用更加方便。如果不是参加竞赛的用户可以使用这一层的驱动来实现STC16F的快速上手,也可以通过查看我们的代码用于寄存器如何使用。目前支持ADC、EXTI、IIC、SPI、PIT、CTIME、UART。如果有需要其他功能亦可直接调用寄存器来实现其他功能。

seekfree_peripheral文件夹下放置的是各类常用的模块驱动,当使用到这些模块时只需要调用函数即可实现相应的功能,非常的简单方便。目前实现线性CCD、1.8寸TFT、ICM20602六轴陀螺仪、IIC通讯协议(模拟IO)、1.14寸IPS液晶屏、MPU6050六轴陀螺仪、OLED显示屏、虚拟示波器通讯协议、无线转串口模块。

CODE文件夹下放置的是用户自己添加的代码文件,当用户自己添加文件的时候我们建议全部添加在这个文件夹内。

USER文件夹下放置的是main.c、isr.h、isr.c文件。

 底层驱动功能模块

目前逐飞STC16F库实现了芯片中ADC、SPI、UART、GPIO、PIT、DELAY、EXTI、CTIMR功能模块的使用,以下几个模块单独说明下:

GPIO模块,STC16位机,还是沿用了以前的89C52引脚控制的思路,通过位绑定去控制引脚,这样就及其方便地控制引脚输出和获取引脚输入。我们所编写的GPIO模块包含了GPIO模式选择,上拉使能。

1.  sfr         P0          =           0x80;  

2.  sbit        P00         =           P0^0;  

3.  sbit        P01         =           P0^1;  

4.  sbit        P02         =           P0^2;  

5.  sbit        P03         =           P0^3;  

6.  sbit        P04         =           P0^4;  

7.  sbit        P05         =           P0^5;  

8.  sbit        P06         =           P0^6;  

9.  sbit        P07         =           P0^7;  

EXTI模块,外部中断模块包含了五个外部中断源触发中断,其中INT0和INT1支持边沿触发+下降沿触发,其他三个只支持下降沿触发。

PWM模块,STC16F具有两组PWM,这样就可以使用一组PWM输出50HZ的频率控制舵机,另外一组PWM输出17KHZ的频率控制电机。

CTIMR模块,CTIMR模块是通过定时器外部计数,作为输入捕获。一共有五个定时器,最多实现五个CTIMER模块,每个模块可以实现一路编码器的脉冲采集,这样就可以采集逐飞带方向输出的编码器数据。

PIT模块,通过定时器模块,进行周期中断。

常用外设模块的底层适配

逐飞开源库包含各个常用外设模块的底层适配 :

 关键位置

在src文件夹下有2个文件,isr.c存放中断函数,main.c放主函数

 main.c内容如下,哪里放初始化函数,哪里放需要循环的代码,这里标记地很清楚

/*********************************************************************************************************************
 * COPYRIGHT NOTICE
 * Copyright (c) 2020,逐飞科技
 * All rights reserved.
 * 技术讨论QQ群:一群:179029047(已满)  二群:244861897(已满)  三群:824575535
 *
 * 以下所有内容版权均属逐飞科技所有,未经允许不得用于商业用途,
 * 欢迎各位使用并传播本程序,修改内容时必须保留逐飞科技的版权声明。
 *
 * @file       		main
 * @company	   		成都逐飞科技有限公司
 * @author     		逐飞科技(QQ790875685)
 * @version    		查看doc内version文件 版本说明
 * @Software 		MDK FOR C251 V5.60
 * @Target core		STC16F40K128
 * @Taobao   		https://seekfree.taobao.com/
 * @date       		2020-12-18
 ********************************************************************************************************************/

#include "headfile.h"


/*
 *关于内核频率的设定,可以查看board.h文件
 *在board_init中,已经将P54引脚设置为复位
 *如果需要使用P54引脚,可以在board.c文件中的board_init()函数中删除SET_P54_RESRT即可
 */


void main()
{
    //sys_clk可选值:33177600, 30000000, 27000000. 24000000, 22118400, 20000000, 18432000, 12000000, 11059200, 6000000, 5529600。
    //设置系统频率,此频率需要跟STC-ISP软件中的 <输入用户程序运行时的IRC频率>选项的频率一致。
    //如果频率设置不对,将会导致串口的数据不正常,PWM的工作不正常等等。
    sys_clk = 30000000;     //设置系统频率为30MHz
    
	board_init();			//初始化寄存器
	//此处编写用户代码(例如:外设初始化代码等)
	
	
    while(1)
	{
        //此处编写需要循环执行的代码
    }
}

isr.c如下:

///*********************************************************************************************************************
// * COPYRIGHT NOTICE
// * Copyright (c) 2020,逐飞科技
// * All rights reserved.
// * 技术讨论QQ群:一群:179029047(已满)  二群:244861897(已满)  三群:824575535
// *
// * 以下所有内容版权均属逐飞科技所有,未经允许不得用于商业用途,
// * 欢迎各位使用并传播本程序,修改内容时必须保留逐飞科技的版权声明。
// *
// * @file       		isr
// * @company	   		成都逐飞科技有限公司
// * @author     		逐飞科技(QQ790875685)
// * @version    		查看doc内version文件 版本说明
// * @Software 			MDK FOR C251 V5.60
// * @Target core		STC16F40K128
// * @Taobao   			https://seekfree.taobao.com/
// * @date       		2020-4-14
// ********************************************************************************************************************/
#include "headfile.h"

//UART1中断
void UART1_Isr() interrupt 4
{
    uint8 res;
	static uint8 dwon_count;
    if(UART1_GET_TX_FLAG)
    {
        UART1_CLEAR_TX_FLAG;
        busy[1] = 0;
    }
    if(UART1_GET_RX_FLAG)
    {
        UART1_CLEAR_RX_FLAG;
        res = SBUF;
        //程序自动下载
        if(res == 0x7F)
        {
            if(dwon_count++ > 20)
                IAP_CONTR = 0x60;
        }
        else
        {
            dwon_count = 0;
        }
    }
}

//UART2中断
void UART2_Isr() interrupt 8
{
    if(UART2_GET_TX_FLAG)
	{
        UART2_CLEAR_TX_FLAG;
		busy[2] = 0;
	}
    if(UART2_GET_RX_FLAG)
	{
        UART2_CLEAR_RX_FLAG;
		//接收数据寄存器为:S2BUF

	}
}


//UART3中断
void UART3_Isr() interrupt 17
{
    if(UART3_GET_TX_FLAG)
	{
        UART3_CLEAR_TX_FLAG;
		busy[3] = 0;
	}
    if(UART3_GET_RX_FLAG)
	{
        UART3_CLEAR_RX_FLAG;
		//接收数据寄存器为:S3BUF

	}
}


//UART4中断
void UART4_Isr() interrupt 18
{
    if(UART4_GET_TX_FLAG)
	{
        UART4_CLEAR_TX_FLAG;
		busy[4] = 0;
	}
    if(UART4_GET_RX_FLAG)
	{
        UART4_CLEAR_RX_FLAG;

		//接收数据寄存器为:S4BUF;
		if(wireless_type == WIRELESS_SI24R1)
        {
            wireless_uart_callback();           //无线转串口回调函数
        }
        else if(wireless_type == WIRELESS_CH9141)
        {
            bluetooth_ch9141_uart_callback();   //蓝牙转串口回调函数
        }
        else if(wireless_type == WIRELESS_CH573)
        {
            wireless_ch573_callback();          //CH573无线模块回调函数
        }
        
	}
}

#define LED P52
void INT0_Isr() interrupt 0
{
	LED = 0;	//点亮LED
}
void INT1_Isr() interrupt 2
{

}
void INT2_Isr() interrupt 10
{
	INT2_CLEAR_FLAG;  //清除中断标志
}
void INT3_Isr() interrupt 11
{
	INT3_CLEAR_FLAG;  //清除中断标志
}

void INT4_Isr() interrupt 16
{
	INT4_CLEAR_FLAG;  //清除中断标志
}

void TM0_Isr() interrupt 1
{

}
void TM1_Isr() interrupt 3
{

}
void TM2_Isr() interrupt 12
{
	TIM2_CLEAR_FLAG;  //清除中断标志
	
}
void TM3_Isr() interrupt 19
{
	TIM3_CLEAR_FLAG; //清除中断标志
	
}

void TM4_Isr() interrupt 20
{
	TIM4_CLEAR_FLAG; //清除中断标志
//	ccd_collect();	 //CCD采集数据

}

//void  INT0_Isr()  interrupt 0;
//void  TM0_Isr()   interrupt 1;
//void  INT1_Isr()  interrupt 2;
//void  TM1_Isr()   interrupt 3;
//void  UART1_Isr() interrupt 4;
//void  ADC_Isr()   interrupt 5;
//void  LVD_Isr()   interrupt 6;
//void  PCA_Isr()   interrupt 7;
//void  UART2_Isr() interrupt 8;
//void  SPI_Isr()   interrupt 9;
//void  INT2_Isr()  interrupt 10;
//void  INT3_Isr()  interrupt 11;
//void  TM2_Isr()   interrupt 12;
//void  INT4_Isr()  interrupt 16;
//void  UART3_Isr() interrupt 17;
//void  UART4_Isr() interrupt 18;
//void  TM3_Isr()   interrupt 19;
//void  TM4_Isr()   interrupt 20;
//void  CMP_Isr()   interrupt 21;
//void  I2C_Isr()   interrupt 24;
//void  USB_Isr()   interrupt 25;
//void  PWM1_Isr()  interrupt 26;
//void  PWM2_Isr()  interrupt 27;

将需要放入中断的函数放入对应位置即可。
注意:使用需进行初始化,eg:

​​​​​​​pit_timer_ms(TIM_4, 1);                //使用TIMER作为周期中断,时间1ms一次

调用模块

 在了解逐飞库的结构之后,接下来尝试驱动一些模块。

逐飞科技的个人空间-逐飞科技个人主页-哔哩哔哩视频

这是逐飞的哔哩哔哩主页,我们找到“核心板与智能车常用模块搭配使用视频教程”系列视频,跟着视频学会调用常用的模块。

应用举例 

下面我以让“屏幕显示字符 ”这一简单的例子,来讲解如何将调用代码,并于实物相联系。

  • 首先看一下,手里的屏幕是什么型号,有哪些引脚 

  • 我这里用1.8寸液晶屏LCD举例,在seekfree_peripheral文件夹下,可以找到18TFT相应的文件,

打开18TFT.h文件,可以看到注释:

                     接线定义:
                    ------------------------------------ 
                    模块管脚            单片机管脚
                    SCL                 查看TFT_SCL宏定义的引脚     硬件SPI引脚不可随意切换
                    SDA                 查看TFT_SDA宏定义的引脚     硬件SPI引脚不可随意切换
                    RES                 查看REST_PIN宏定义的引脚    
                    DC                  查看DC_PIN宏定义的引脚  
                    CS                  查看TFT_CS宏定义的引脚      硬件SPI引脚不可随意切换
                    
                    电源引脚
                    BL  3.3V电源(背光控制引脚,也可以接PWM来控制亮度)
                    VCC 3.3V电源
                    GND 电源地
                    最大分辨率128*160
                    ------------------------------------ 

 然后代码里定义了单片机管脚

//--------------------软件SPI--------------------


#define	TFT_SCL_SIMSPI_PIN 		P25				//定义SPI_SCK引脚
#define	TFT_SDA_SIMSPI_PIN		P23   			//定义SPI_MOSI引脚
#define TFT_REST_SIMSPI_PIN  	P20				//定义复位引脚
#define TFT_DC_SIMSPI_PIN	  	P21				//液晶命令位引脚定义
#define TFT_CS_SIMSPI_PIN	  	P22				//定义SPI_CS引脚
#define TFT_BL_SIMSPI_PIN	  	P27				//液晶背光引脚定义  


#define	TFT_SCL_SIMSPI(x)	(TFT_SCL_SIMSPI_PIN	 = x)
#define	TFT_SDA_SIMSPI(x)	(TFT_SDA_SIMSPI_PIN	 = x)
#define TFT_REST_SIMSPI(x) 	(TFT_REST_SIMSPI_PIN = x)	
#define TFT_DC_SIMSPI(x)   	(TFT_DC_SIMSPI_PIN	 = x)
#define TFT_CS_SIMSPI(x) 	(TFT_CS_SIMSPI_PIN	 = x)
#define TFT_BL_SIMSPI(x) 	(TFT_BL_SIMSPI_PIN	 = x)



//--------------------硬件SPI--------------------


#define TFT_SPIN 		SPI_CH2			//定义使用的SPI号
#define	TFT_SCL_PIN 	SPI_CH2_SCLK_P25	//定义SPI_SCK引脚
#define	TFT_SDA_PIN		SPI_CH2_MOSI_P23   //定义SPI_MOSI引脚
#define	TFT_SDA_IN_PIN	SPI_CH2_MISO_P24   //定义SPI_MISO引脚  TFT屏幕没有MISO引脚,但是这里任然需要定义,在spi的初始化时需要使用
#define TFT_REST_PIN  	P20
#define TFT_DC_PIN	  	P21				//液晶命令位引脚定义
#define TFT_CS_PIN	  	P22				//定义SPI_CS引脚
#define TFT_BL_PIN	  	P27				//液晶背光引脚定义  


#define TFT_REST(x) (TFT_REST_PIN= x)	
#define TFT_DC(x)   (TFT_DC_PIN	 = x)
#define TFT_CS(x) 	(TFT_CS_PIN	 = x)
#define TFT_BL(x) 	(TFT_BL_PIN	 = x)

根据上面的两个信息,我们可以将屏幕和单片机用杜邦线联系起来。

  •  这里是TFT的一些函数,jiaru

 使用屏幕之前需要初始化,对应的是这个函数

void lcd_init(void);

我们要显示一个字符,对应的是这个

void lcd_showchar(uint16 x,uint16 y,const int8 dat);

右击鼠标,点go to definition 可以看到该函数的定义


//-------------------------------------------------------------------------------------------------------------------
//  @brief      液晶显示字符
//  @param      x     	        坐标x方向的起点 参数范围 0 -(TFT_X_MAX-1)
//  @param      y     	        坐标y方向的起点 参数范围 0 -(TFT_Y_MAX/16-1)
//  @param      dat       	    需要显示的字符
//  @return     void
//  @since      v1.0
//  Sample usage:               lcd_showchar(0,0,'x');//坐标0,0写一个字符x
//-------------------------------------------------------------------------------------------------------------------
void lcd_showchar(uint16 x,uint16 y,const int8 dat)
{
	uint8 i,j;
	uint8 temp;
    
	for(i=0; i<16; i++)
	{
		lcd_set_region(x,y+i,x+7,y+i);
		temp = tft_ascii[dat-32][i];//减32因为是取模是从空格开始取得 空格在ascii中序号是32
		for(j=0; j<8; j++)
		{
			if(temp&0x01)	lcd_writedata_16bit(TFT_PENCOLOR);
			else			lcd_writedata_16bit(TFT_BGCOLOR);
			temp>>=1;
		}
	}
}

 接下来就开始调用代码了,

打开main.c

首先,放上初始化函数

接着,我们在while里放上显示字符的函数:

#include "headfile.h"


void main()
{
    //sys_clk可选值:33177600, 30000000, 27000000. 24000000, 22118400, 20000000, 18432000, 12000000, 11059200, 6000000, 5529600。
    //设置系统频率,此频率需要跟STC-ISP软件中的 <输入用户程序运行时的IRC频率>选项的频率一致。
    //如果频率设置不对,将会导致串口的数据不正常,PWM的工作不正常等等。
    sys_clk = 30000000;     //设置系统频率为30MHz
    
	board_init();			//初始化寄存器
	//此处编写用户代码(例如:外设初始化代码等)
	lcd_init();
	
    while(1)
	{
        //此处编写需要循环执行的代码
		lcd_showchar(0,0,'X');
    }
}

 然后,编译、烧录、上电,就实现了在屏幕上显示一个字符X


系列文章目录

文章分为三个层次

速通版

是希望通过简化的步骤搭建出寻迹小车,进而了解整个智能车是如何实现的,快速上手,为后续参与智能车竞赛做基础。

如果只是为了完成学校智能车初期培训,做出能简单循迹的小车,可以看这个速通版。

全程引导篇

是讲了做出能够完赛的智能车的整个过程,大部分文章只是简单点拨一下,但是附上了相关的文章链接,方便根据自己的情况深入了解。

全程引导篇,能够带你比较系统地了解整个智能车的制作过程,推荐备赛初期或者有车模之后学习。

详细讲解篇

是全程引导篇的补充,由于全程引导篇是引导性质,文章内容只是点拨,缺乏相应的原理或代码讲解,因此写详细讲解篇作为补充。

详细讲解篇会渗透在全程引导篇中。


速通版

智能小车速通版——手把手教程

全程引导篇

智能小车速通版——教程引导(原版)

智能小车速通版——教程引导

智能车入门——IDE安装以及库函数选用

智能车入门——编程语言(c)的学习

智能车入门——简单驱动常用模块

智能车入门——车模器件篇

智能车入门——模块化编程

智能车入门——跑车前的零碎知识

智能车入门——电磁循迹原理与实现

智能车入门——实现低速完赛

详细讲解篇

智能车入门补充篇

智能车入门补充篇——逐飞开源库介绍

智能车入门补充篇——常见宏定义和使用

智能车入门补充篇——模块化编程

智能车入门补充篇——电感值处理、转向控制与巡线

智能车入门补充篇——元素识别

智能车模块详解——按键及按键调参

智能车模块详解——数据存储与读写(eeprom/flash)

智能车入门——I/O、PWM

智能车入门——中断

智能车入门——编码器

智能车入门——陀螺仪

智能车入门——摄像头和CCD

智能车入门——舵机

(更新中)

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_lucky_R

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值