Commit 77827826 by zhanggf

Init openbci project.

Signed-off-by: zhanggf <zhanggf@example.com>
parents
#ifndef __ADS129x_H
#define __ADS129x_H
#include "sys.h"
#include "myQueue.h"
///////////////////////////////////////////////////////////////////////////////
//芯片及功能选择
#define ADS1298 1
#define ADS1299 2
#define ADS1292 3
#define ADS129X_USE_SPI1 1
#define ADS129X_USE_SPI2 2
#define ADS129X_USE_SPI3 3
///////////////////////////////////////////////////////////////////////////////
//芯片及功能选择
#define ADS129X_DEVICE ADS1299 //芯片选择
#define ADS129X_UART_DEBUG 1 //寄存器串口调试 //1 使用寄存器串口调试 0不适用
#define ADS129X_CASCADE_NUM 1 //设备级联数量
#define ADS129X_USE_CANNLE 8 //芯片使用N个通道
#define ADS129X_USE_DMA 0 //开启DMA
////////////////////////////////////////////////////////////////////////////////////////////
//注意导联脱落功能会影响输入阻抗:无导联脱落 1000M 电流源导联脱落 500M 上拉电阻导联脱落 10M
#define ADS129X_LEADOFF 0 //导联脱落检测功能 1开启 0关闭
////////////////////////////////////////////////////////////////////////////////////////////
//测试数据选项(优先级 锯齿波>方波>噪声)
#define ADS129X_USE_TRIANGLE_TESTDATA 0 //通道1使用锯齿波自增测试数据 //1 使用测试数据 0不使用 虚拟数据,不使用ADS129X
#define ADS129X_USE_SQUARE_TESTDATA 0 //使用内部方波数据 //1 使用测试数据 0不使用 方波数据,通过ADS129X采集
#define ADS129X_USE_NOISE_TESTDATA 0 //测试内部短接噪声
/////////////////////////////////////////////////////////////////////////////////////////////
//引脚及通讯接口
#define ADS129X_USE_SPI ADS129X_USE_SPI1 //SPI选择
#define ADS129X_DRDY_LINE EXTI_Line0//DRDY中断通道
#define ADS129X_DRDY PBin(0)
#define ADS129X_CS PAout(12)
#define ADS129X_RST PAout(15)
/////////////////////////////////////////////////////////////////////////////////////////////
//芯片寄存器数量及中断读取的字节数
#if ADS129X_DEVICE == ADS1298
#define ADS129X_REGNUM 26 //寄存器数量
#define ADS129X_DATANUM 27 //一次DRDY中断的数据读取数量
#elif ADS129X_DEVICE == ADS1299
#define ADS129X_REGNUM 24 //寄存器数量
#define ADS129X_DATANUM 27 //数据读取数量
#elif ADS129X_DEVICE == ADS1292
#define ADS129X_REGNUM 12 //寄存器数量
#define ADS129X_DATANUM 9 //数据读取数量
#endif
/////////////////////////////////////////////////////////////////////////////////////////////
__align(4) typedef struct
{
u8 Ads129x_DRDY_flag; //DRDY中断
u8 Ads129x_Cascade_Num;//芯片级联数量
u8 Ads129x_Use_Cannle;//一个芯片使用N个通道
u16 Ads129x_Data_Move; //每次中断搬运N个数据 ADS129X_Data_Move = Ads129x_USE_Cannle*3
u16 Ads129x_Write_Num; //搬运N次 做一个包 ADS129x_Write_Num = ADS129x_SAMPLING_POINT / Ads129x_USE_Cannle
u32 Ads129x_leadoff_flag;//导联脱离标志
u8 Ads129x_test_flag; //自增测试数据
u16 Ads129x_err_time;
u8 ads129x_Cache[27]; //129x数据缓冲区
u32 cannle[12]; //存储原始的数据
s32 p_Temp[12]; //存储原始的数据
//QueueInfo *ADS129x_Queue;//数据缓冲区指针
}_ADS129x_info;
extern _ADS129x_info ADS129x_info;//芯片结构
extern u8 ADS129x_REG_BUF[ADS129X_REGNUM];//ads1299寄存器数组
/////////////////////////////////////////////////////////////////////////////////////////////
//串口DEBUG
#if ADS129X_UART_DEBUG == 1
#define ADS129X_DEBUG(...) Main_printf(__VA_ARGS__)
#else
#define ADS129X_DEBUG(...)
#endif
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
//命令定义
//注意: 开机默认处于 RDATAC 模式时,要读写寄存器必须先发送SDATAC命令
//如果器件处于 RDATAC 模式,则必须先发出 SDATAC命令,然后才能将任何其他命令发送到器件中。
//系统命令
#define ADS129X_WAKEUP 0X02 //从待机模式唤醒
#define ADS129X_STANDBY 0X04 //进入待机模式
#define ADS129X_RESET 0X06 //复位
#define ADS129X_START 0X08 //启动转换
#define ADS129X_STOP 0X0A //停止转换
//数据读取命令
#define ADS129X_RDATAC 0X10 //启用连续的数据读取模式,默认使用此模式
#define ADS129X_SDATAC 0X11 //停止连续的数据读取模式
#define ADS129X_RDATA 0X12 //通过命令读取数据;支持多个读回。
//寄存器读取命令
//r rrrr=要读、写的寄存器首地址 // n nnnn=要读写的寄存器数量
#define ADS129X_RREG 0X20 //读取 001r rrrr(首字节) 000n nnnn(2字节)
#define ADS129X_WREG 0X40 //写入 010r rrrr(首字节) 000n nnnn(2字节)
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
s32 get_volt(u32 num);//把采到的3个字节转成有符号32位数
void ADS129x_GPIO_Init(void); //初始化ADS1292引脚
void ADS129x_ReInit(u8 cmd);//重复初始化
u8 ADS129x_SPI_ReadWriteByte(u8 com); //SPI通信
__INLINE void ADS129x_Read_Data(void);//72M时钟下函数耗时大约10us 8M时钟下 函数耗时大约 100us
#endif
/* //默认寄存器值 1298
0 92
1 6
2 0
3 40
4 0
5 0
6 0
7 0
8 0
9 0
10 0
11 0
12 0
13 0
14 0
15 0
16 0
17 0
18 0
19 0
20 f
21 0
22 0
23 0
24 0
25 0
*/
/* //默认寄存器值 1299
0 3e
1 96
2 c0
3 60
4 0
5 61
6 61
7 61
8 61
9 61
10 61
11 61
12 61
13 0
14 0
15 0
16 0
17 0
18 0
19 0
20 f
21 0
22 0
23 0
*/
\ No newline at end of file
#ifndef __EXFUNS_H
#define __EXFUNS_H
#include <sys.h>
#include "ff.h"
/*********************************************************************************
___ _ _____ _____ _ _ _____ _____ _ __
/ _ \ | | |_ _|| ___|| \ | ||_ _|| ___|| | / /
/ /_\ \| | | | | |__ | \| | | | | |__ | |/ /
| _ || | | | | __| | . ` | | | | __| | \
| | | || |_____| |_ | |___ | |\ | | | | |___ | |\ \
\_| |_/\_____/\___/ \____/ \_| \_/ \_/ \____/ \_| \_/
* ******************************************************************************
* 本程序只供学习使用,未经作者许可,不得用于其它任何用途
* ALIENTEK Pandora STM32L475 IOT开发板
* FATFS 测试代码
* 正点原子@ALIENTEK
* 技术论坛:www.openedv.com
* 创建日期:2018/10/27
* 版本:V1.0
* 版权所有,盗版必究。
* Copyright(C) 广州市星翼电子科技有限公司 2014-2024
* All rights reserved
* ******************************************************************************
* 初始版本
* ******************************************************************************/
extern FATFS *fs[_VOLUMES];
extern FIL *file;
extern FIL *ftemp;
extern UINT br,bw;
extern FILINFO fileinfo;
extern DIR dir;
extern u8 *fatbuf;//SD卡数据缓存区
//f_typetell返回的类型定义
//根据表FILE_TYPE_TBL获得.在exfuns.c里面定义
#define T_BIN 0X00 //bin文件
#define T_LRC 0X10 //lrc文件
#define T_NES 0X20 //nes文件
#define T_SMS 0X21 //sms文件
#define T_TEXT 0X30 //.txt文件
#define T_C 0X31 //.c文件
#define T_H 0X32 //.h文件
#define T_WAV 0X40 //WAV文件
#define T_MP3 0X41 //MP3文件
#define T_APE 0X42 //APE文件
#define T_FLAC 0X43 //FLAC文件
#define T_BMP 0X50 //bmp文件
#define T_JPG 0X51 //jpg文件
#define T_JPEG 0X52 //jpeg文件
#define T_GIF 0X53 //gif文件
#define T_AVI 0X60 //avi文件
u8 exfuns_init(void); //申请内存
u8 f_typetell(u8 *fname); //识别文件类型
u8 exf_getfree(u8 *drv,u32 *total,u32 *free); //得到磁盘总容量和剩余容量
u32 exf_fdsize(u8 *fdname); //得到文件夹大小
u8* exf_get_src_dname(u8* dpfn);
u8 exf_copy(u8(*fcpymsg)(u8*pname,u8 pct,u8 mode),u8 *psrc,u8 *pdst,u32 totsize,u32 cpdsize,u8 fwmode); //文件复制
u8 exf_fdcopy(u8(*fcpymsg)(u8*pname,u8 pct,u8 mode),u8 *psrc,u8 *pdst,u32 *totsize,u32 *cpdsize,u8 fwmode);//文件夹复制
#endif
#include "fattester.h"
#include "sd_card.h"
#include "usart.h"
#include "exfuns.h"
#include "malloc.h"
#include "ff.h"
#include "string.h"
/*********************************************************************************
___ _ _____ _____ _ _ _____ _____ _ __
/ _ \ | | |_ _|| ___|| \ | ||_ _|| ___|| | / /
/ /_\ \| | | | | |__ | \| | | | | |__ | |/ /
| _ || | | | | __| | . ` | | | | __| | \
| | | || |_____| |_ | |___ | |\ | | | | |___ | |\ \
\_| |_/\_____/\___/ \____/ \_| \_/ \_/ \____/ \_| \_/
* ******************************************************************************
* 本程序只供学习使用,未经作者许可,不得用于其它任何用途
* ALIENTEK Pandora STM32L475 IOT开发板
* FATFS 测试代码
* 正点原子@ALIENTEK
* 技术论坛:www.openedv.com
* 创建日期:2018/10/27
* 版本:V1.0
* 版权所有,盗版必究。
* Copyright(C) 广州市星翼电子科技有限公司 2014-2024
* All rights reserved
* ******************************************************************************
* 初始版本
* ******************************************************************************/
/**
* @brief 为磁盘注册工作区
*
* @param path 磁盘路径,比如"0:"、"1:"
* @param mt 0,不立即注册(稍后注册);1,立即注册
*
* @return u8 执行结果
*/
u8 mf_mount(u8* path,u8 mt)
{
return f_mount(fs[1],(const TCHAR*)path,mt);
}
/**
* @brief 打开路径下的文件
*
* @param path 路径+文件名
* @param mode 打开模式
*
* @return u8 执行结果
*/
u8 mf_open(u8*path,u8 mode)
{
u8 res;
res=f_open(file,(const TCHAR*)path,mode);//打开文件夹
return res;
}
/**
* @brief 关闭文件
*
* @param void
*
* @return u8 执行结果
*/
u8 mf_close(void)
{
f_close(file);
return 0;
}
/**
* @brief 读出数据
*
* @param len 读出的长度
*
* @return u8 执行结果
*/
u8 mf_read(u16 len)
{
u16 i,t;
u8 res=0;
u16 tlen=0;
printf("\r\nRead file data is:\r\n");
for(i=0;i<len/512;i++)
{
res=f_read(file,fatbuf,512,&br);
if(res)
{
printf("Read Error:%d\r\n",res);
break;
}else
{
tlen+=br;
for(t=0;t<br;t++)printf("%c",fatbuf[t]);
}
}
if(len%512)
{
res=f_read(file,fatbuf,len%512,&br);
if(res) //读数据出错了
{
printf("\r\nRead Error:%d\r\n",res);
}else
{
tlen+=br;
for(t=0;t<br;t++)printf("%c",fatbuf[t]);
}
}
if(tlen)printf("\r\nReaded data len:%d\r\n",tlen);//读到的数据长度
printf("Read data over\r\n");
return res;
}
/**
* @brief 写入数据
*
* @param dat 数据缓存区
* @param len 写入长度
*
* @return u8 执行结果
*/
u8 mf_write(u8*dat,u16 len)
{
u8 res;
printf("\r\nBegin Write file...\r\n");
printf("Write data len:%d\r\n",len);
res=f_write(file,dat,len,&bw);
if(res)
{
printf("Write Error:%d\r\n",res);
}else printf("Writed data len:%d\r\n",bw);
printf("Write data over.\r\n");
return res;
}
/**
* @brief 打开目录
*
* @param path 路径
*
* @return u8 执行结果
*/
u8 mf_opendir(u8* path)
{
return f_opendir(&dir,(const TCHAR*)path);
}
/**
* @brief 关闭目录
*
* @param void
*
* @return u8 执行结果
*/
u8 mf_closedir(void)
{
return f_closedir(&dir);
}
/**
* @brief 打读取文件夹
*
* @param void
*
* @return u8 执行结果
*/
u8 mf_readdir(void)
{
u8 res;
res=f_readdir(&dir,&fileinfo); //读取一个文件的信息
if(res!=FR_OK)return res; //出错了
printf("\r\n DIR info:\r\n");
printf("dir.dptr:%d\r\n",dir.dptr);
printf("dir.obj.id:%d\r\n",dir.obj.id);
printf("dir.obj.sclust:%d\r\n",dir.obj.sclust);
printf("dir.obj.objsize:%lld\r\n",dir.obj.objsize);
printf("dir.obj.c_ofs:%d\r\n",dir.obj.c_ofs);
printf("dir.clust:%d\r\n",dir.clust);
printf("dir.sect:%d\r\n",dir.sect);
printf("dir.blk_ofs:%d\r\n",dir.blk_ofs);
printf("\r\n");
printf("File Name is:%s\r\n",fileinfo.fname);
printf("File Size is:%lld\r\n",fileinfo.fsize);
printf("File data is:%d\r\n",fileinfo.fdate);
printf("File time is:%d\r\n",fileinfo.ftime);
printf("File Attr is:%d\r\n",fileinfo.fattrib);
printf("\r\n");
return 0;
}
/**
* @brief 遍历文件
*
* @param path 路径
*
* @return u8 执行结果
*/
u8 mf_scan_files(u8 * path)
{
FRESULT res;
res = f_opendir(&dir,(const TCHAR*)path); //打开一个目录
if (res == FR_OK)
{
printf("\r\n");
while(1)
{
res = f_readdir(&dir, &fileinfo); //读取目录下的一个文件
if (res != FR_OK || fileinfo.fname[0] == 0) break; //错误了/到末尾了,退出
//if (fileinfo.fname[0] == '.') continue; //忽略上级目录
printf("%s/", path);//打印路径
printf("%s\r\n",fileinfo.fname);//打印文件名
}
}
return res;
}
/**
* @brief 显示剩余容量
*
* @param drv 盘符
*
* @return u8 剩余容量(字节)
*/
u32 mf_showfree(u8 *drv)
{
FATFS *fs1;
u8 res;
u32 fre_clust=0, fre_sect=0, tot_sect=0;
//得到磁盘信息及空闲簇数量
res = f_getfree((const TCHAR*)drv,(DWORD*)&fre_clust, &fs1);
if(res==0)
{
tot_sect = (fs1->n_fatent - 2) * fs1->csize;//得到总扇区数
fre_sect = fre_clust * fs1->csize; //得到空闲扇区数
#if _MAX_SS!=512
tot_sect*=fs1->ssize/512;
fre_sect*=fs1->ssize/512;
#endif
if(tot_sect<20480)//总容量小于10M
{
/* Print free space in unit of KB (assuming 512 bytes/sector) */
printf("\r\n磁盘总容量:%d KB\r\n"
"可用空间:%d KB\r\n",
tot_sect>>1,fre_sect>>1);
}else
{
/* Print free space in unit of KB (assuming 512 bytes/sector) */
printf("\r\n磁盘总容量:%d MB\r\n"
"可用空间:%d MB\r\n",
tot_sect>>11,fre_sect>>11);
}
}
return fre_sect;
}
/**
* @brief 文件读写指针偏移
*
* @param offset 相对首地址的偏移量
*
* @return u8 执行结果
*/
u8 mf_lseek(u32 offset)
{
return f_lseek(file,offset);
}
/**
* @brief 读取文件当前读写指针的位置
*
* @param void
*
* @return u32 位置
*/
u32 mf_tell(void)
{
return f_tell(file);
}
/**
* @brief 读取文件大小
*
* @param void
*
* @return u32 文件大小
*/
u32 mf_size(void)
{
return f_size(file);
}
/**
* @brief 创建目录
*
* @param pname 目录路径+名字
*
* @return u8 执行结果
*/
u8 mf_mkdir(u8*pname)
{
return f_mkdir((const TCHAR *)pname);
}
/**
* @brief 格式化
*
* @param path 磁盘路径,比如"0:"、"1:"
* @param mode 模式
* @param au 簇大小
*
* @return u8 执行结果
*/
u8 mf_fmkfs(u8* path,u8 mode,u16 au)
{
return f_mkfs((const TCHAR*)path,mode,au);//格式化,drv:盘符;mode:模式;au:簇大小
}
/**
* @brief 删除文件/目录
*
* @param pname 文件/目录路径+名字
*
* @return u8 执行结果
*/
u8 mf_unlink(u8 *pname)
{
return f_unlink((const TCHAR *)pname);
}
/**
* @brief 修改文件/目录名字(如果目录不同,还可以移动文件哦!)
*
* @param oldname:之前的名字
* @param newname:新名字
*
* @return u8 执行结果
*/
u8 mf_rename(u8 *oldname,u8* newname)
{
return f_rename((const TCHAR *)oldname,(const TCHAR *)newname);
}
/**
* @brief 获取盘符(磁盘名字)
*
* @param path 磁盘路径,比如"0:"、"1:"
*
* @return void
*/
void mf_getlabel(u8 *path)
{
u8 buf[20];
u32 sn=0;
u8 res;
res=f_getlabel ((const TCHAR *)path,(TCHAR *)buf,(DWORD*)&sn);
if(res==FR_OK)
{
printf("\r\n磁盘%s 的盘符为:%s\r\n",path,buf);
printf("磁盘%s 的序列号:%X\r\n\r\n",path,sn);
}else printf("\r\n获取失败,错误码:%X\r\n",res);
}
/**
* @brief 设置盘符(磁盘名字),最长11个字符!!,支持数字和大写字母组合以及汉字等
*
* @param path 磁盘号+名字,比如"0:ALIENTEK"、"1:OPENEDV"
*
* @return void
*/
void mf_setlabel(u8 *path)
{
u8 res;
res=f_setlabel ((const TCHAR *)path);
if(res==FR_OK)
{
printf("\r\n磁盘盘符设置成功:%s\r\n",path);
}else printf("\r\n磁盘盘符设置失败,错误码:%X\r\n",res);
}
/**
* @brief 从文件里面读取一段字符串
*
* @param size 要读取的长度
*
* @return void
*/
void mf_gets(u16 size)
{
TCHAR* rbuf;
rbuf=f_gets((TCHAR*)fatbuf,size,file);
if(*rbuf==0)return ;//没有数据读到
else
{
printf("\r\nThe String Readed Is:%s\r\n",rbuf);
}
}
/**
* @brief 需要_USE_STRFUNC>=1,写一个字符到文件
*
* @param c: 要写入的字符
*
* @return u8 执行结果
*/
u8 mf_putc(u8 c)
{
return f_putc((TCHAR)c,file);
}
/**
* @brief 写字符串到文件
*
* @param c: 要写入的字符串
*
* @return u8 写入的字符串长度
*/
u8 mf_puts(u8*c)
{
return f_puts((TCHAR*)c,file);
}
#ifndef __FATTESTER_H
#define __FATTESTER_H
#include "sys.h"
#include "ff.h"
/*********************************************************************************
___ _ _____ _____ _ _ _____ _____ _ __
/ _ \ | | |_ _|| ___|| \ | ||_ _|| ___|| | / /
/ /_\ \| | | | | |__ | \| | | | | |__ | |/ /
| _ || | | | | __| | . ` | | | | __| | \
| | | || |_____| |_ | |___ | |\ | | | | |___ | |\ \
\_| |_/\_____/\___/ \____/ \_| \_/ \_/ \____/ \_| \_/
* ******************************************************************************
* 本程序只供学习使用,未经作者许可,不得用于其它任何用途
* ALIENTEK Pandora STM32L475 IOT开发板
* FATFS 测试代码
* 正点原子@ALIENTEK
* 技术论坛:www.openedv.com
* 创建日期:2018/10/27
* 版本:V1.0
* 版权所有,盗版必究。
* Copyright(C) 广州市星翼电子科技有限公司 2014-2024
* All rights reserved
* ******************************************************************************
* 初始版本
* ******************************************************************************/
u8 mf_mount(u8* path,u8 mt);
u8 mf_open(u8*path,u8 mode);
u8 mf_close(void);
u8 mf_read(u16 len);
u8 mf_write(u8*dat,u16 len);
u8 mf_opendir(u8* path);
u8 mf_closedir(void);
u8 mf_readdir(void);
u8 mf_scan_files(u8 * path);
u32 mf_showfree(u8 *drv);
u8 mf_lseek(u32 offset);
u32 mf_tell(void);
u32 mf_size(void);
u8 mf_mkdir(u8*pname);
u8 mf_fmkfs(u8* path,u8 mode,u16 au);
u8 mf_unlink(u8 *pname);
u8 mf_rename(u8 *oldname,u8* newname);
void mf_getlabel(u8 *path);
void mf_setlabel(u8 *path);
void mf_gets(u16 size);
u8 mf_putc(u8 c);
u8 mf_puts(u8*c);
#endif
FatFs Module Source Files R0.12
FILES
00readme.txt This file.
history.txt Revision history.
ffconf.h Configuration file for FatFs module.
ff.h Common include file for FatFs and application module.
ff.c FatFs module.
diskio.h Common include file for FatFs and disk I/O module.
diskio.c An example of glue function to attach existing disk I/O module to FatFs.
integer.h Integer type definitions for FatFs.
option Optional external functions.
Low level disk I/O module is not included in this archive because the FatFs
module is only a generic file system layer and not depend on any specific
storage device. You have to provide a low level disk I/O module that written
to control the target storage device.
/*-----------------------------------------------------------------------*/
/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2016 */
/*-----------------------------------------------------------------------*/
/* If a working storage control module is available, it should be */
/* attached to the FatFs via a glue function rather than modifying it. */
/* This is an example of glue functions to attach various exsisting */
/* storage control modules to the FatFs module with a defined API. */
/*-----------------------------------------------------------------------*/
#include "diskio.h" /* FatFs lower layer API */
#include "sd_card.h"
//#include "w25qxx.h"
#include "malloc.h"
#include "usart.h" //串口
/*********************************************************************************
___ _ _____ _____ _ _ _____ _____ _ __
/ _ \ | | |_ _|| ___|| \ | ||_ _|| ___|| | / /
/ /_\ \| | | | | |__ | \| | | | | |__ | |/ /
| _ || | | | | __| | . ` | | | | __| | \
| | | || |_____| |_ | |___ | |\ | | | | |___ | |\ \
\_| |_/\_____/\___/ \____/ \_| \_/ \_/ \____/ \_| \_/
* ******************************************************************************
* 本程序只供学习使用,未经作者许可,不得用于其它任何用途
* ALIENTEK Pandora STM32L475 IOT开发板
* FATFS底层(diskio)驱动代码
* 正点原子@ALIENTEK
* 技术论坛:www.openedv.com
* 创建日期:2018/10/27
* 版本:V1.0
* 版权所有,盗版必究。
* Copyright(C) 广州市星翼电子科技有限公司 2014-2024
* All rights reserved
* ******************************************************************************
* 初始版本
* ******************************************************************************/
#define SD_CARD 0 //SD卡,卷标为0
#define EX_FLASH 1 //外部spi flash,卷标为1
/***********************************************************************
SPI FLASH(W25Q128)资源分配
序号 偏移地址 大小 存储内容
1 0x00000000 0x00200000 预留给RT Thread使用(2M)
2 0x00200000 0x00603000 预留给中文字库使用(6156K)
3 0x00803000 0x000FD000 预留给用户使用(1012K)
4 0x00900000 0x00700000 预留给FATFS使用(7M)
************************************************************************/
//对于W25Q128
#define FLASH_SECTOR_SIZE 512
#define FLASH_SECTOR_COUNT 1024*7*2 //W25Q128,最后7M字节给FATFS占用
#define FLASH_BLOCK_SIZE 8 //每个BLOCK有8个扇区
#define FLASH_Offset_Addr ((16-7)*1024*1024) //最后7M空间给FATFS使用
/**
* @brief 获取磁盘状态
*
* @param pdrv 磁盘编号
*
* @return u8 RES_OK
*/
DSTATUS disk_status (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
return RES_OK;
}
/**
* @brief 初始化磁盘
*
* @param pdrv 磁盘编号
*
* @return u8 0:初始化成功,1:初始化失败
*/
DSTATUS disk_initialize (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
u8 res=0;
switch(pdrv)
{
case SD_CARD: //SD卡
res=SD_Initialize(); //SD卡初始化
//Main_printf("初始化 %d ",res);
break;
// case EX_FLASH: //外部flash
// W25QXX_Init(); //W25QXX初始化
// break;
default:
res=1;
}
if(res)return STA_NOINIT;
else return 0; //初始化成功
}
/**
* @brief 读扇区
*
* @param pdrv 磁盘编号
* @param buff 数据接收缓冲首地址
* @param sector 扇区地址
* @param count 需要读取的扇区数
*
* @return DRESULT RES_OK:成功,RES_ERROR:失败
*/
DRESULT disk_read (
BYTE pdrv, /* Physical drive nmuber to identify the drive */
BYTE *buff, /* Data buffer to store read data */
DWORD sector, /* Sector address in LBA */
UINT count /* Number of sectors to read */
)
{
u8 res=0;
if (!count)return RES_PARERR;//count不能等于0,否则返回参数错误
switch(pdrv)
{
case SD_CARD://SD卡
res=SD_ReadDisk(buff,sector,count);
while(res)//读出错
{
SD_Initialize(); //重新初始化SD卡
res=SD_ReadDisk(buff,sector,count);
//Main_printf("读出错 %d ",res);
//printf("sd rd error:%d\r\n",res);
}
break;
// case EX_FLASH://外部flash
// for(;count>0;count--)
// {
// W25QXX_Read(buff,sector*FLASH_SECTOR_SIZE+FLASH_Offset_Addr,FLASH_SECTOR_SIZE);
// sector++;
// buff+=FLASH_SECTOR_SIZE;
// }
// res=0;
// break;
default:
res=1;
}
//处理返回值,将SPI_SD_driver.c的返回值转成ff.c的返回值
if(res==0x00)return RES_OK;
else return RES_ERROR;
}
/**
* @brief 写扇区
*
* @param pdrv 磁盘编号0~9
* @param buff 发送数据首地址
* @param sector 扇区地址
* @param count 需要写入的扇区数
*
* @return DRESULT RES_OK:成功,RES_ERROR:失败
*/
DRESULT disk_write (
BYTE pdrv, /* Physical drive nmuber to identify the drive */
const BYTE *buff, /* Data to be written */
DWORD sector, /* Sector address in LBA */
UINT count /* Number of sectors to write */
)
{
u8 res=0;
if (!count)return RES_PARERR;//count不能等于0,否则返回参数错误
switch(pdrv)
{
case SD_CARD://SD卡
res=SD_WriteDisk((u8*)buff,sector,count);
//发送数据首地址 指向BUF缓冲区
//Main_printf("写返回%d 要写入的扇区地址 %d 要写扇区数 %d\r\n",res,sector,count);
//Main_printf("写%d 发送数据首地址 %d 扇区地址 %d 要写扇区数 %d\r\n",res,buff,sector,count);
while(res)//写出错
{
SD_Initialize(); //重新初始化SD卡
res=SD_WriteDisk((u8*)buff,sector,count);
//Main_printf("写出错 %d ",res);
//printf("sd wr error:%d\r\n",res);
}
break;
// case EX_FLASH://外部flash
// for(;count>0;count--)
// {
// W25QXX_Write((u8*)buff,sector*FLASH_SECTOR_SIZE+FLASH_Offset_Addr,FLASH_SECTOR_SIZE);
// sector++;
// buff+=FLASH_SECTOR_SIZE;
// }
// res=0;
// break;
default:
res=1;
}
//处理返回值,将SPI_SD_driver.c的返回值转成ff.c的返回值
if(res == 0x00)return RES_OK;
else return RES_ERROR;
}
/**
* @brief 控制设备指定特性和除了读/写外的杂项功能
*
* @param pdrv 磁盘编号0~9
* @param ctrl 指定命令代码
* @param buff 指向参数缓冲区首地址,取决于命令,无参数时,指向 NULL
*
* @return DRESULT 请参考DRESULT定义
*/
DRESULT disk_ioctl (
BYTE pdrv, /* Physical drive nmuber (0..) */
BYTE cmd, /* Control code */
void *buff /* Buffer to send/receive control data */
)
{
DRESULT res;
if(pdrv==SD_CARD)//SD卡
{
switch(cmd)
{
case CTRL_SYNC:
res = RES_OK;
break;
case GET_SECTOR_SIZE:
*(DWORD*)buff = 512;
res = RES_OK;
break;
case GET_BLOCK_SIZE:
*(WORD*)buff = 8;
res = RES_OK;
break;
case GET_SECTOR_COUNT:
*(DWORD*)buff = SD_GetSectorCount();
res = RES_OK;
break;
default:
res = RES_PARERR;
break;
}
}
// else if(pdrv==EX_FLASH) //外部FLASH
// {
// switch(cmd)
// {
// case CTRL_SYNC:
// res = RES_OK;
// break;
// case GET_SECTOR_SIZE:
// *(WORD*)buff = FLASH_SECTOR_SIZE;
// res = RES_OK;
// break;
// case GET_BLOCK_SIZE:
// *(WORD*)buff = FLASH_BLOCK_SIZE;
// res = RES_OK;
// break;
// case GET_SECTOR_COUNT:
// *(DWORD*)buff = FLASH_SECTOR_COUNT;
// res = RES_OK;
// break;
// default:
// res = RES_PARERR;
// break;
// }
// }
else res=RES_ERROR;//其他的不支持
return res;
}
/**
* @brief 为fatfs模块提供当前时间
* 31-25: Year(0-127 org.1980), 24-21: Month(1-12), 20-16: Day(1-31)
* 15-11: Hour(0-23), 10-5: Minute(0-59), 4-0: Second(0-29 *2)
*
* @param pdrv 磁盘编号0~9
* @param ctrl 指定命令代码
* @param buff 指向参数缓冲区首地址,取决于命令,无参数时,指向 NULL
*
* @return DWORD 时间数据
*/
DWORD get_fattime (void)
{
return 0;
}
/**
* @brief 动态分配内存
*
* @param size 申请内存大小
*
* @return void* 分配到的内存首地址
*/
void *ff_memalloc (UINT size)
{
return (void*)mymalloc(size);
}
/**
* @brief 释放内存
*
* @param mf 内存首地址
*
* @return void
*/
void ff_memfree (void* mf)
{
myfree(mf);
}
/*-----------------------------------------------------------------------/
/ Low level disk interface modlue include file (C)ChaN, 2014 /
/-----------------------------------------------------------------------*/
#ifndef _DISKIO_DEFINED
#define _DISKIO_DEFINED
#ifdef __cplusplus
extern "C" {
#endif
#include "integer.h"
/* Status of Disk Functions */
typedef BYTE DSTATUS;
/* Results of Disk Functions */
typedef enum {
RES_OK = 0, /* 0: Successful */
RES_ERROR, /* 1: R/W Error */
RES_WRPRT, /* 2: Write Protected */
RES_NOTRDY, /* 3: Not Ready */
RES_PARERR /* 4: Invalid Parameter */
} DRESULT;
/*---------------------------------------*/
/* Prototypes for disk control functions */
DSTATUS disk_initialize (BYTE pdrv);
DSTATUS disk_status (BYTE pdrv);
DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count);
DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);
DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
/* Disk Status Bits (DSTATUS) */
#define STA_NOINIT 0x01 /* Drive not initialized */
#define STA_NODISK 0x02 /* No medium in the drive */
#define STA_PROTECT 0x04 /* Write protected */
/* Command code for disk_ioctrl fucntion */
/* Generic command (Used by FatFs) */
#define CTRL_SYNC 0 /* Complete pending write process (needed at _FS_READONLY == 0) */
#define GET_SECTOR_COUNT 1 /* Get media size (needed at _USE_MKFS == 1) */
#define GET_SECTOR_SIZE 2 /* Get sector size (needed at _MAX_SS != _MIN_SS) */
#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at _USE_MKFS == 1) */
#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at _USE_TRIM == 1) */
/* Generic command (Not used by FatFs) */
#define CTRL_POWER 5 /* Get/Set power status */
#define CTRL_LOCK 6 /* Lock/Unlock media removal */
#define CTRL_EJECT 7 /* Eject media */
#define CTRL_FORMAT 8 /* Create physical format on the media */
/* MMC/SDC specific ioctl command */
#define MMC_GET_TYPE 10 /* Get card type */
#define MMC_GET_CSD 11 /* Get CSD */
#define MMC_GET_CID 12 /* Get CID */
#define MMC_GET_OCR 13 /* Get OCR */
#define MMC_GET_SDSTAT 14 /* Get SD status */
#define ISDIO_READ 55 /* Read data form SD iSDIO register */
#define ISDIO_WRITE 56 /* Write data to SD iSDIO register */
#define ISDIO_MRITE 57 /* Masked write data to SD iSDIO register */
/* ATA/CF specific ioctl command */
#define ATA_GET_REV 20 /* Get F/W revision */
#define ATA_GET_MODEL 21 /* Get model name */
#define ATA_GET_SN 22 /* Get serial number */
#ifdef __cplusplus
}
#endif
#endif
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed. Click to expand it.
/*-------------------------------------------*/
/* Integer type definitions for FatFs module */
/*-------------------------------------------*/
#ifndef _FF_INTEGER
#define _FF_INTEGER
#ifdef _WIN32 /* FatFs development platform */
#include <windows.h>
#include <tchar.h>
typedef unsigned __int64 QWORD;
#else /* Embedded platform */
/* These types MUST be 16-bit or 32-bit */
typedef int INT;
typedef unsigned int UINT;
/* This type MUST be 8-bit */
typedef unsigned char BYTE;
/* These types MUST be 16-bit */
typedef short SHORT;
typedef unsigned short WORD;
typedef unsigned short WCHAR;
/* These types MUST be 32-bit */
typedef long LONG;
typedef unsigned long DWORD;
/* This type MUST be 64-bit (Remove this for C89 compatibility) */
typedef unsigned long long QWORD;
#endif
#endif
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
#include "ff.h"
//////////////////////////////////////////////////////////////////////////////////
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK MiniSTM32开发板
//cc936.c修改后 代码
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//修改日期:2014/3/14
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2009-2019
//All rights reserved
//////////////////////////////////////////////////////////////////////////////////
//Unicode 与 GBK 是两个完全不样的字符编码方案, 其两者没有直接关系,
//要对其进行相互转换, 最直接最高效的方法是查表.
//显示汉字,并不需要内码转换,默认的编码就是GBK,直接查找字库就是了
//内码转换发生在UNICODE转GBK或者GBK转UNICODE的时候,比如创建文件,或者读取文件名的时候。
WCHAR ff_convert ( /* Converted code, 0 means conversion error */
WCHAR src, /* Character code to be converted */
UINT dir /* 0: Unicode to OEMCP, 1: OEMCP to Unicode */
)
{
WCHAR t[2];
WCHAR c;
unsigned int i, li, hi;
unsigned short int n;
unsigned int gbk2uni_offset=0;
if (src < 0x80)//ASCII,直接不用转换. 区分中文编码的方法是高字节的最高位不为0
c = src;
else //汉字
{
// if(dir) //GBK TO UNICODE
// {
// gbk2uni_offset=ftinfo.ugbksize/2;
// }
// else //UNICODE TO GBK
// {
// gbk2uni_offset=0;
// }
//
// // Unicode to OEMCP
// hi=ftinfo.ugbksize/2;//对半开.
// hi =hi / 4 - 1;
// li = 0;
// for (n = 16; n; n--)
// {
// i = li + (hi - li) / 2;
// W25QXX_Read((u8*)&t,ftinfo.ugbkaddr+i*4+gbk2uni_offset,4);//读出4个字节
// if (src == t[0]) break;
// if (src > t[0])li = i;
// else hi = i;
// }
// c = n ? t[1] : 0;
}
return c;
}
WCHAR ff_wtoupper ( /* Upper converted character 转换字符*/
WCHAR chr /* Input character */
)
{
static const WCHAR tbl_lower[] = { 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, 0xA1, 0x00A2, 0x00A3, 0x00A5, 0x00AC, 0x00AF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0x0FF, 0x101, 0x103, 0x105, 0x107, 0x109, 0x10B, 0x10D, 0x10F, 0x111, 0x113, 0x115, 0x117, 0x119, 0x11B, 0x11D, 0x11F, 0x121, 0x123, 0x125, 0x127, 0x129, 0x12B, 0x12D, 0x12F, 0x131, 0x133, 0x135, 0x137, 0x13A, 0x13C, 0x13E, 0x140, 0x142, 0x144, 0x146, 0x148, 0x14B, 0x14D, 0x14F, 0x151, 0x153, 0x155, 0x157, 0x159, 0x15B, 0x15D, 0x15F, 0x161, 0x163, 0x165, 0x167, 0x169, 0x16B, 0x16D, 0x16F, 0x171, 0x173, 0x175, 0x177, 0x17A, 0x17C, 0x17E, 0x192, 0x3B1, 0x3B2, 0x3B3, 0x3B4, 0x3B5, 0x3B6, 0x3B7, 0x3B8, 0x3B9, 0x3BA, 0x3BB, 0x3BC, 0x3BD, 0x3BE, 0x3BF, 0x3C0, 0x3C1, 0x3C3, 0x3C4, 0x3C5, 0x3C6, 0x3C7, 0x3C8, 0x3C9, 0x3CA, 0x430, 0x431, 0x432, 0x433, 0x434, 0x435, 0x436, 0x437, 0x438, 0x439, 0x43A, 0x43B, 0x43C, 0x43D, 0x43E, 0x43F, 0x440, 0x441, 0x442, 0x443, 0x444, 0x445, 0x446, 0x447, 0x448, 0x449, 0x44A, 0x44B, 0x44C, 0x44D, 0x44E, 0x44F, 0x451, 0x452, 0x453, 0x454, 0x455, 0x456, 0x457, 0x458, 0x459, 0x45A, 0x45B, 0x45C, 0x45E, 0x45F, 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x217A, 0x217B, 0x217C, 0x217D, 0x217E, 0x217F, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57, 0xFF58, 0xFF59, 0xFF5A, 0 };
static const WCHAR tbl_upper[] = { 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, 0x21, 0xFFE0, 0xFFE1, 0xFFE5, 0xFFE2, 0xFFE3, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0x178, 0x100, 0x102, 0x104, 0x106, 0x108, 0x10A, 0x10C, 0x10E, 0x110, 0x112, 0x114, 0x116, 0x118, 0x11A, 0x11C, 0x11E, 0x120, 0x122, 0x124, 0x126, 0x128, 0x12A, 0x12C, 0x12E, 0x130, 0x132, 0x134, 0x136, 0x139, 0x13B, 0x13D, 0x13F, 0x141, 0x143, 0x145, 0x147, 0x14A, 0x14C, 0x14E, 0x150, 0x152, 0x154, 0x156, 0x158, 0x15A, 0x15C, 0x15E, 0x160, 0x162, 0x164, 0x166, 0x168, 0x16A, 0x16C, 0x16E, 0x170, 0x172, 0x174, 0x176, 0x179, 0x17B, 0x17D, 0x191, 0x391, 0x392, 0x393, 0x394, 0x395, 0x396, 0x397, 0x398, 0x399, 0x39A, 0x39B, 0x39C, 0x39D, 0x39E, 0x39F, 0x3A0, 0x3A1, 0x3A3, 0x3A4, 0x3A5, 0x3A6, 0x3A7, 0x3A8, 0x3A9, 0x3AA, 0x410, 0x411, 0x412, 0x413, 0x414, 0x415, 0x416, 0x417, 0x418, 0x419, 0x41A, 0x41B, 0x41C, 0x41D, 0x41E, 0x41F, 0x420, 0x421, 0x422, 0x423, 0x424, 0x425, 0x426, 0x427, 0x428, 0x429, 0x42A, 0x42B, 0x42C, 0x42D, 0x42E, 0x42F, 0x401, 0x402, 0x403, 0x404, 0x405, 0x406, 0x407, 0x408, 0x409, 0x40A, 0x40B, 0x40C, 0x40E, 0x40F, 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0x216A, 0x216B, 0x216C, 0x216D, 0x216E, 0x216F, 0xFF21, 0xFF22, 0xFF23, 0xFF24, 0xFF25, 0xFF26, 0xFF27, 0xFF28, 0xFF29, 0xFF2A, 0xFF2B, 0xFF2C, 0xFF2D, 0xFF2E, 0xFF2F, 0xFF30, 0xFF31, 0xFF32, 0xFF33, 0xFF34, 0xFF35, 0xFF36, 0xFF37, 0xFF38, 0xFF39, 0xFF3A, 0 };
int i;
for (i = 0; tbl_lower[i] && chr != tbl_lower[i]; i++) ;
return tbl_lower[i] ? tbl_upper[i] : chr;
}
/*------------------------------------------------------------------------*/
/* Sample code of OS dependent controls for FatFs */
/* (C)ChaN, 2014 */
/*------------------------------------------------------------------------*/
#include "../ff.h"
#if _FS_REENTRANT
/*------------------------------------------------------------------------*/
/* Create a Synchronization Object
/*------------------------------------------------------------------------*/
/* This function is called in f_mount() function to create a new
/ synchronization object, such as semaphore and mutex. When a 0 is returned,
/ the f_mount() function fails with FR_INT_ERR.
*/
int ff_cre_syncobj ( /* 1:Function succeeded, 0:Could not create the sync object */
BYTE vol, /* Corresponding volume (logical drive number) */
_SYNC_t *sobj /* Pointer to return the created sync object */
)
{
int ret;
*sobj = CreateMutex(NULL, FALSE, NULL); /* Win32 */
ret = (int)(*sobj != INVALID_HANDLE_VALUE);
// *sobj = SyncObjects[vol]; /* uITRON (give a static sync object) */
// ret = 1; /* The initial value of the semaphore must be 1. */
// *sobj = OSMutexCreate(0, &err); /* uC/OS-II */
// ret = (int)(err == OS_NO_ERR);
// *sobj = xSemaphoreCreateMutex(); /* FreeRTOS */
// ret = (int)(*sobj != NULL);
return ret;
}
/*------------------------------------------------------------------------*/
/* Delete a Synchronization Object */
/*------------------------------------------------------------------------*/
/* This function is called in f_mount() function to delete a synchronization
/ object that created with ff_cre_syncobj() function. When a 0 is returned,
/ the f_mount() function fails with FR_INT_ERR.
*/
int ff_del_syncobj ( /* 1:Function succeeded, 0:Could not delete due to any error */
_SYNC_t sobj /* Sync object tied to the logical drive to be deleted */
)
{
int ret;
ret = CloseHandle(sobj); /* Win32 */
// ret = 1; /* uITRON (nothing to do) */
// OSMutexDel(sobj, OS_DEL_ALWAYS, &err); /* uC/OS-II */
// ret = (int)(err == OS_NO_ERR);
// vSemaphoreDelete(sobj); /* FreeRTOS */
// ret = 1;
return ret;
}
/*------------------------------------------------------------------------*/
/* Request Grant to Access the Volume */
/*------------------------------------------------------------------------*/
/* This function is called on entering file functions to lock the volume.
/ When a 0 is returned, the file function fails with FR_TIMEOUT.
*/
int ff_req_grant ( /* 1:Got a grant to access the volume, 0:Could not get a grant */
_SYNC_t sobj /* Sync object to wait */
)
{
int ret;
ret = (int)(WaitForSingleObject(sobj, _FS_TIMEOUT) == WAIT_OBJECT_0); /* Win32 */
// ret = (int)(wai_sem(sobj) == E_OK); /* uITRON */
// OSMutexPend(sobj, _FS_TIMEOUT, &err)); /* uC/OS-II */
// ret = (int)(err == OS_NO_ERR);
// ret = (int)(xSemaphoreTake(sobj, _FS_TIMEOUT) == pdTRUE); /* FreeRTOS */
return ret;
}
/*------------------------------------------------------------------------*/
/* Release Grant to Access the Volume */
/*------------------------------------------------------------------------*/
/* This function is called on leaving file functions to unlock the volume.
*/
void ff_rel_grant (
_SYNC_t sobj /* Sync object to be signaled */
)
{
ReleaseMutex(sobj); /* Win32 */
// sig_sem(sobj); /* uITRON */
// OSMutexPost(sobj); /* uC/OS-II */
// xSemaphoreGive(sobj); /* FreeRTOS */
}
#endif
#if _USE_LFN == 3 /* LFN with a working buffer on the heap */
/*------------------------------------------------------------------------*/
/* Allocate a memory block */
/*------------------------------------------------------------------------*/
/* If a NULL is returned, the file function fails with FR_NOT_ENOUGH_CORE.
*/
void* ff_memalloc ( /* Returns pointer to the allocated memory block */
UINT msize /* Number of bytes to allocate */
)
{
return malloc(msize); /* Allocate a new memory block with POSIX API */
}
/*------------------------------------------------------------------------*/
/* Free a memory block */
/*------------------------------------------------------------------------*/
void ff_memfree (
void* mblock /* Pointer to the memory block to free */
)
{
free(mblock); /* Discard the memory block with POSIX API */
}
#endif
#include "../ff.h"
#if _USE_LFN != 0
#if _CODE_PAGE == 932 /* Japanese Shift_JIS */
#include "cc932.c"
#elif _CODE_PAGE == 936 /* Simplified Chinese GBK */
#include "cc936.c"
#elif _CODE_PAGE == 949 /* Korean */
#include "cc949.c"
#elif _CODE_PAGE == 950 /* Traditional Chinese Big5 */
#include "cc950.c"
#else /* Single Byte Character-Set */
#include "ccsbcs.c"
#endif
#endif
#include "ESP8266.h"
#include "usart.h"
#include <string.h>
#include "delay.h"
#include "led.h"
#include "key.h"
#include "Timer.h"
#include "ADS129x.h"
#include "myQueue.h"
_WIFI_Info *WIFI_Info ; //WIFI数据结构
//TCP传输需要手动设置 WIFI名称 密码 IP地址 端口
u8 M8266_CWJAP[60]="AT+CWJAP=\"OPPORENO\",\"12345678\"\r\n"; //连接AP ssid: xxx 密码:xxx
//u8 M8266_CIPSTART[60]="AT+CIPSTART=\"TCP\",\"192.168.43.1\",10500\r\n";
u8 M8266_SAVETRANSLINK[60] = "AT+SAVETRANSLINK=1,\"192.168.0.166\",8083,\"TCP\"\r\n";//保存配网信息
//匿名发送数据格式
//AA AA F1 21(4*8+1=33) ... test CHECK //4+32+1+1=38字节 8通道数据
//38次采样1帧 队列长度1444字节
u8 Wifi_Sendbuf_Init(void)
{
u16 i;
WIFI_Info->datalength = (ADS129X_USE_CANNLE+1)*4 +3;//一次采样要发送的数据长度 39
memset(WIFI_Info->sendbuf,0,WIFI_SEND_LENGTH);//清零
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//匿名上位机协议
for(i=0;i<ADS129x_info.Ads129x_Write_Num;i++) //一包N次采样
{
//帧头
WIFI_Info->sendbuf[0 + WIFI_Info->datalength*i] = 0xAA;
WIFI_Info->sendbuf[1 + WIFI_Info->datalength*i] = 0xFF;
WIFI_Info->sendbuf[2 + WIFI_Info->datalength*i] = 0xF1;
WIFI_Info->sendbuf[3 + WIFI_Info->datalength*i] = ADS129X_USE_CANNLE*4 +1; //有效数据长度 32 +1 = 33
}
return 1;
}
//发送指令,并判断指定字符串是否缓冲区中
//返回-1 没有指定的串
//0-125 字符串在数组中的位置
s16 ESP8266_SendCmd(u8* cmd, u8* result, u16 timeOut)
{
s16 res;
ESP8266_CLEAR();//清空缓冲区
USARTx_Send(ESP8266_UART,(uint8_t*) cmd, strlen(cmd));
delay_ms(timeOut);
//ESP8266_DEBUG("ESP8266 rsp:%s \r\n",ESP8266_RX_BUF);
res = Str_search(ESP8266_RX_BUF,ESP8266_RX_LEN,result);//查询字符串
return res;
}
//IO初始化
void ESP8266_IO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能PB端口时钟
//B6
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; //IO口速度为2MHz
GPIO_Init(GPIOB, &GPIO_InitStructure);
ESP8266_PWOEROFF;
//ESP8266_RST=1; //复位
}
u8 ESP8266_SET_FLAG=0;
//设置检测
void ESP8266_SET(void)
{
u16 ret=0;
if (KEYPWR == 0)//按键按下
{
LED_2=LED_ON;
while( KEYPWR == 0)
{
delay_ms(10);
ret++;
if ( ret > 300 )//3s
{
LED_2=LED_OFF;
ESP8266_SET_FLAG=1;//设置蓝牙
while( KEYPWR == 0);
return ;//退出函数
}
}
LED_2=LED_OFF;
}
}
void ESP8266_Config(void)
{
ESP8266_Goto_Cmd();//进入AT指令模式
ESP8266_DEBUG("设置工作模式:STA \r\n");
while(1)
{
if(ESP8266_SendCmd(CWMODE, "OK", 500) >= 0)//模块工作模式 设置AP模式
break;
else
LED2=!LED2;
}
ESP8266_DEBUG("设置工作模式:单链接 \r\n");
while(1)
{
if(ESP8266_SendCmd(CIPMUX, "OK", 500) >= 0)//设置单链接模式,用于透传,开机默认单链接
break;
else
LED2=!LED2;
}
ESP8266_DEBUG("\r\n等待连接WIFI\r\n");
while(1)
{
if(ESP8266_SendCmd(M8266_CWJAP, "OK", 1500) >= 0)//连接AP WIFI热点SSID和密码
break;
else
{
LED2=!LED2;
ESP8266_DEBUG("等待 ");
}
}
ESP8266_DEBUG("\r\n查看IP地址");
while(1)
{
if(ESP8266_SendCmd(CIFSR, "OK", 500) >= 0)//查询连接
break;
else
{
LED2=!LED2;
ESP8266_DEBUG("等待 ");
}
}
ESP8266_DEBUG("\r\n建立TCP连接 \r\n");
while(1)
{
if(ESP8266_SendCmd(M8266_SAVETRANSLINK, "OK", 500) >= 0)//建立TCP连接
break;
else
{
LED2=!LED2;
ESP8266_DEBUG("失败");
}
}
ESP8266_DEBUG("\r\n设置波特率透传 \r\n");
while(1)
{
if(ESP8266_SendCmd(ESP_USARTDEF, "OK", 500) >= 0)//设置波特率 及流控
break;
else
LED2=!LED2;
}
ESP8266_uart_init(ESP_BAUD); //初始化
ESP8266_out_Cmd();//退出指令模式
LED1=LED_OFF;
LED2=LED_OFF;
ESP8266_DEBUG("设置成功\r\n");
}
//进入AT指令模式
void ESP8266_Goto_Cmd(void)
{
delay_ms(500);
ESP8266_PWOEROFF;
delay_ms(500);
ESP8266_PWOERON;
// ESP8266_RST=0;
// delay_ms(500);
// ESP8266_RST=1;
// delay_ms(500);
ESP8266_DEBUG("进入AT指令模式\r\n");
ESP8266_DEBUG("默认波特率 %d\r\n",ESP_BAUD);
ESP8266_uart_init(ESP_BAUD);
ESP8266_SendCmd("+++", "OK", 1200);//退出透传
if(ESP8266_SendCmd(AT, "OK", 500) >= 0) //模块有效性检查
{
ESP8266_DEBUG("WIFI初始化成功\r\n");
return;
}
while(1)
{
ESP8266_DEBUG("当前波特率 115200\r\n");
ESP8266_uart_init(115200);
ESP8266_SendCmd("+++", "OK", 1200);//退出透传
if(ESP8266_SendCmd(AT, "OK", 500) >= 0) //模块有效性检查
{
break;
}
else
LED2=!LED2;
ESP8266_DEBUG("当前波特率 460800\r\n");
ESP8266_uart_init(460800);
ESP8266_SendCmd("+++", "OK", 1200);//退出透传
if(ESP8266_SendCmd(AT, "OK", 500) >= 0) //模块有效性检查
{
break;
}
else
LED2=!LED2;
ESP8266_DEBUG("当前波特率 921600\r\n");
ESP8266_uart_init(921600);
ESP8266_SendCmd("+++", "OK", 1200);//退出透传
if(ESP8266_SendCmd(AT, "OK", 500) >= 0) //模块有效性检查
{
break;
}
else
LED2=!LED2;
}
//ESP8266_SendCmd(RST, "OK", 500) ;//复位
//USART_ITConfig(ESP8266_UART, USART_IT_RXNE, DISABLE);//串口接收中断
}
//进入透传模式
void ESP8266_out_Cmd(void)
{
ESP8266_DEBUG("退出AT指令模式\r\n");
ESP8266_SendCmd(RST, "OK", 500) ;//复位
USART_ITConfig(ESP8266_UART, USART_IT_RXNE, DISABLE);//串口接收中断
}
void ESP8266_Init(void)
{
//ESP8266_PWOEROFF;
//delay_ms(200);
ESP8266_PWOERON;
delay_s(2);
// ESP8266_RST=0;
// delay_ms(500);
// ESP8266_RST=1;
// delay_ms(500);
ESP8266_DEBUG("进入AT指令模式\r\n");
ESP8266_DEBUG("默认波特率 %d\r\n",ESP_BAUD);
ESP8266_uart_init(ESP_BAUD);
ESP8266_SendCmd("+++", "OK", 1200);//退出透传
if(ESP8266_SendCmd(AT, "OK", 500) >= 0) //模块有效性检查
{
ESP8266_DEBUG("WIFI初始化成功\r\n");
ESP8266_SendCmd(RST, "OK", 500) ;//复位
USART_ITConfig(ESP8266_UART, USART_IT_RXNE, DISABLE);//串口接收中断
return;
}
else
{
ESP8266_DEBUG("无响应,按照默认参数设置\r\n");
ESP8266_Config();//设置WIFI
}
}
//串口配网
void Set_WIFI(void)
{
u8 u_recbuf[200];
u16 u_reclen;
Main_printf("开启AT配网\r\n");
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//串口接受中断
LED1=LED_OFF;
LED2=LED_OFF;
Main_printf("网络及IP设置\r\n\r\n");
Main_printf("AT配网,有效内容不要超60字节,例:\r\n\r\n");
Main_printf("设置名称密码 : AT+CWJAP_DEF=\"OPPORENO\",\"12345678\"\r\n");
Main_printf("设置TCP连接 : AT+SAVETRANSLINK=1,\"192.168.0.166\",8083,\"TCP\"\r\n");
Main_printf("退出设置 : AT+OVER\r\n\r\n");
while(1)
{
if(USART_RX_STA & 0x8000)//接收到数据
{
//搬运数据
u_reclen=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
memcpy(u_recbuf,USART_RX_BUF,u_reclen);//复制内容
USART_RX_STA=0;
if(u_recbuf[0]=='A' && u_recbuf[1]=='T' && u_recbuf[2]=='+')//AT指令
{
if( u_recbuf[3]=='C' && u_recbuf[4]=='W' && u_recbuf[5]=='J' && u_recbuf[6]=='A'
&& u_recbuf[7]=='P' && u_recbuf[8]=='_' && u_recbuf[9]=='D' && u_recbuf[10]=='E'
&& u_recbuf[11]=='F' && u_recbuf[12]=='=') //设置名称
{
Main_printf("设置名称密码指令:");
memset(M8266_CWJAP, 0, 60);
memcpy(M8266_CWJAP,u_recbuf,u_reclen);//复制内容
M8266_CWJAP[u_reclen] = 0x0d;
M8266_CWJAP[u_reclen+1] = 0x0a;
ESP8266_DEBUG("%s\r\n",M8266_CWJAP);
}
else if( u_recbuf[3]=='S' && u_recbuf[4]=='A' && u_recbuf[5]=='V' && u_recbuf[6]=='E'
&& u_recbuf[7]=='T' && u_recbuf[8]=='R' && u_recbuf[9]=='A' && u_recbuf[10]=='N'
&& u_recbuf[11]=='S' && u_recbuf[12]=='L' && u_recbuf[13]=='I' && u_recbuf[14]=='N'
&& u_recbuf[15]=='K' && u_recbuf[16]=='=') //设置名称
{
Main_printf("设置IP端口指令:");
memset(M8266_SAVETRANSLINK, 0, 60);
memcpy(M8266_SAVETRANSLINK,u_recbuf,u_reclen);//复制内容
M8266_SAVETRANSLINK[u_reclen] = 0x0d;
M8266_SAVETRANSLINK[u_reclen+1] = 0x0a;
ESP8266_DEBUG("%s\r\n",M8266_SAVETRANSLINK);
}
else if(u_recbuf[3]=='O' && u_recbuf[4]=='V' && u_recbuf[5]=='E' && u_recbuf[6]=='R') //设置完成
{
Main_printf("请等待设置完成\r\n");
break;
}
else
{
Main_printf("错误的指令\r\n");
}
}
}
else
{
delay_ms(10);
}
}
USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);//关闭串口接受中断
//要设置的参数
Main_printf("要设置名称密码: %s",M8266_CWJAP);
Main_printf("要设置TCP连接: %s\r\n",M8266_SAVETRANSLINK);
ESP8266_Config(); //设置开机自动透传
LED1=LED_OFF;
LED2=LED_OFF;
}
#ifndef __ESP8266_H
#define __ESP8266_H
#include "sys.h"
#include "myQueue.h"
#define _ESP8266_DEBUG_ 1 //串口调试开关
/////////////////////////////////////////////////////////////////////////////////////////////
#define ESP8266_UART USART2
#define ESP8266_uart_init(x) uart2_init(x)
#define ESP8266_RX_BUF USART2_RX_BUF
#define ESP8266_RX_LEN USART2_RX_LEN
#define ESP8266_CLEAR() USART2_Clear()
//#define ESP8266_RST PBout(5)
#define ESP8266_POWER PBout(6)
#define ESP8266_PWOERON ESP8266_POWER=0
#define ESP8266_PWOEROFF ESP8266_POWER=1
/////////////////////////////////////////////////////////////////////////////////////////////
//WIFI数据接收
#define ADS129x_WIFI_REC_EN 0 //WiFi接收使能
#define WIFI_REC_LENGTH 1460 //接收缓冲区
//匿名上位机
#define WIFI_SEND_LENGTH 1443 //发送缓冲区 一帧数据长度39一帧`次采样 39*37=1444
#define WIFI_QUEUE_LENGTH 888 //(队列容量)缓冲区有效数据长度24*37=888
#define WIFI_QUEUE_SIZE 10 //队列大小
/////////////////////////////////////////////////////////////////////////////////////////////
//发送数据格式
typedef struct {
u16 datalength;
u8 *sendbuf; //发送缓冲区
u8 *recbuf; //接收缓冲区
QueueInfo *WIFI_Queue; //队列结构
}_WIFI_Info;
extern _WIFI_Info *WIFI_Info ; //上传数据结构
////////////////////////////////////////////////////////////////////////////////
//串口DEBUG
#if _ESP8266_DEBUG_ == 1
#define ESP8266_DEBUG(...) Main_printf(__VA_ARGS__)
#else
#define ESP8266_DEBUG(...)
#endif
////////////////////////////////////////////////////////////////////////////////
#define AT "AT\r\n"
#define CWMODE "AT+CWMODE_DEF=1\r\n" //设置STA模式
#define CWAUTOCONN "AT+CWAUTOCONN=1\r\n" //开机进入透传
#define RST "AT+RST\r\n"
#define CIPMUX "AT+CIPMUX=0\r\n" //设置单链接模式,用于透传,开机默认单链接
#define CIFSR "AT+CIFSR\r\n" //查询本地IP地址,只有连上AP后才能查询,返回OK 或者ERR
#define CIPMODE "AT+CIPMODE=1\r\n" //设置透传模式
#define CIPSEND "AT+CIPSEND\r\n" //发送数据,必须开启透传及单链接,换行返回>
//#define ESP_BAUD 460800 //波特率
////#define ESP_USARTDEF "AT+UART_DEF=460800,8,1,0,0\r\n" //修改波特率 无流控 保存到flash
//#define ESP_USARTDEF "AT+UART_DEF=460800,8,1,0,1\r\n" //修改波特率 使能RTS流控 保存到flash
#define ESP_BAUD 921600 //波特率
//#define ESP_USARTDEF "AT+UART_DEF=921600,8,1,0,0\r\n" //修改波特率 无流控 保存到flash
#define ESP_USARTDEF "AT+UART_DEF=921600,8,1,0,1\r\n" //修改波特率 使能RTS流控 保存到flash
////////////////////////////////////////////////////////////////////////////////
//TCP传输需要手动设置 WIFI名称 密码 IP地址 端口
extern u8 M8266_CWJAP[60]; //连接AP ssid: xxx 密码:xxx
extern u8 M8266_SAVETRANSLINK[60];//保存配网信息
extern u8 ESP8266_SET_FLAG;
s16 ESP8266_SendCmd(u8* cmd, u8* result, u16 timeOut);
void ESP8266_IO_Init(void);
void ESP8266_Goto_Cmd(void);
void ESP8266_out_Cmd(void);
void ESP8266_Init(void);
void ESP8266_Config(void);
void ESP8266_SET(void); //配网检测
void Set_WIFI(void);//配网设置
u8 Wifi_Sendbuf_Init(void);
#endif
#include "Timer.h"
#include "led.h"
#include "key.h"
#include "adc.h"
//高级 TIM1 TIM8
//通用 TIM2 TIM3 TIM4 TIM5
//基本 TIM6 TIM7
//C8T6 只有 1-4 4个定时器
u32 Tim1_flag;
void TIM1_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);
TIM_TimeBaseStructure.TIM_Period=arr-1; // 自动重装载寄存器的值
TIM_TimeBaseStructure.TIM_Prescaler=psc-1; // 时钟预分频数
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; // 采样分频
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数
TIM_TimeBaseStructure.TIM_RepetitionCounter=0; //重复寄存器,用于自动更新pwm占空比
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置中断分组
NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn; //TIM中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //先占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //从优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure);
TIM_ClearITPendingBit(TIM1, TIM_IT_Update|TIM_IT_Trigger); //清除更新中断请求位
TIM_ITConfig(TIM1, TIM_IT_Update|TIM_IT_Trigger, ENABLE );//允许更新
TIM_Cmd(TIM1, DISABLE);
}
//定时器中断服务程序
void TIM1_UP_IRQHandler(void)
{
if(TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET) //更新中断
{
TIM_ClearITPendingBit(TIM1, TIM_IT_Update);//清中断标志
Tim1_flag++;
}
}
//定时器初始化
void TIM2_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //TIM5时钟使能
TIM_TimeBaseStructure.TIM_Period = arr-1;; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =psc-1; //设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置中断分组
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; //TIM中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //先占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //从优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure);
TIM_ClearITPendingBit(TIM2, TIM_IT_Update); //清除更新中断请求位
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE );//允许更新
TIM_Cmd(TIM2, ENABLE);
}
u8 TIM2_FLAG=0;
//定时器中断服务程序
void TIM2_IRQHandler(void)
{
if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) //更新中断
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);//清中断标志
TIM2_FLAG++;
if(TIM2_FLAG == 1)
{
if(KEY_STATE&KEY_PWR && KEYPWR == 0)
{
KEY_TYPE = KEY_PWR;
}
}
else if(TIM2_FLAG==5)
{
TIM2_FLAG=0;
TIM_Cmd(TIM2, DISABLE);
TIM2->CNT=0;
KEY_STATE=0;
}
}
}
//定时器初始化
//按键检测
void TIM3_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能
TIM_TimeBaseStructure.TIM_Period = arr-1;; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =psc-1; //设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置中断分组
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //先占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //从优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure);
TIM_ClearITPendingBit(TIM3, TIM_IT_Update); //清除更新中断请求位
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE );//允许更新
TIM_Cmd(TIM3, DISABLE);
}
//定时器中断服务程序
void TIM3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //更新中断
{
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);//清中断标志
TIM_Cmd(TIM3, DISABLE);
TIM3->CNT=KEYDOWNLONGTIME; //长按键
}
}
//定时器初始化
void TIM4_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //时钟使能
TIM_TimeBaseStructure.TIM_Period = arr-1; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =psc-1; //设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置中断分组
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; //TIM中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //先占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //从优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure);
TIM_ClearITPendingBit(TIM4, TIM_IT_Update); //清除更新中断请求位
TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE );//允许更新
TIM_Cmd(TIM4, ENABLE);
}
u8 TIM4_Timing=0;
//定时器中断服务程序
void TIM4_IRQHandler(void)
{
//更新中断
if(TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET) //更新中断
{
TIM4_Timing++;
if(lowpower==0) //低电量指示
{
if( power_detective==1)//开启电量监测
{
BAT_Percent= ((ADCConvertedValue[0]-BAT_0)*100/BAT_LEVEL);
//Main_printf("%d %d mV %d %%\r\n",ADCConvertedValue[0],ADCConvertedValue[0]*3300/4096*2,BAT_Percent);
if(BAT_Percent<10)//低电量
{
lowpower=1;
TIM4_Init(1000,7200);//系统指示灯+电量监测
DS2=LED_ON;
}
}
}
DS1=!DS1;
TIM_ClearITPendingBit(TIM4, TIM_IT_Update);//清中断标志
}
}
/*先说TIM_ARRPreloadConfig设置为DISABLE 和ENABLE的问题,他的作用只是允许或禁止在定时器工作时
向ARR的缓冲器中写入新值,以便在更新事件发生时载入覆盖以前的值。在开始初始化的时候你已经把
TIM_TimeBaseStructure.TIM_Period=2000; //ARR的值
后来也一直是这个值,原因是你没有编写中断服务函数或者你在中断服务函数中根本就没有给ARR缓冲器重新
写入新值,所以设置为DISABLE 和ENABLE都没有影响。*/
//TIM_ARRPreloadConfig(TIM3, ENABLE); //使能TIMx在ARR上的预装载寄存器
//如:关掉TIM3_CH2的PWM输出:TIM3->CCER&=0xFFEF; 关闭 PWM输出
//TIM_OC1NPolarityConfig(TIM1,TIM_OCNPolarity_Low); //关闭输出后,再强制输出电平
// TIM3->CNT=0;//清空定时器计数器
// TIM3->ARR=arr; //设定计数器自动重装值//刚好1ms
// TIM3->PSC=psc; //预分频器7200,得到10Khz的计数时钟
// TIM3->DIER|=1<<0; //允许更新中断
// TIM3->CR1|=0x01; //使能定时器3
\ No newline at end of file
#include "sys.h"
extern u32 Tim1_flag;
extern u8 TIM2_FLAG;
extern u8 TIM4_Timing;
void TIM1_Init(u16 arr,u16 psc);
void TIM2_Init(u16 arr,u16 psc);
void TIM3_Init(u16 arr,u16 psc);
void TIM4_Init(u16 arr,u16 psc);
void TIM5_Init(u16 arr,u16 psc);
void TIM6_Init(u16 arr,u16 psc);
void TIM7_Init(u16 arr,u16 psc);
void TIM8_Init(u16 arr,u16 psc);
#include "adc.h"
#include "dma.h"
//1)ADC接在APB2上,时钟为72MHz,通过分频的方式给ADC 提供时钟,预分频有2、4、6、8 四种方式。
//2)通道采样时间,通道采样时间会影响采样的精度。
//3)转换时间 公式:TCONV = 采样时间+ 12.5 个周期
// 例如:当ADCCLK=14MHz 和1.5 周期的采样时间 TCONV = 1.5 + 12.5 = 14 周期 = 1μs
// 1)一般情况,如果是软件启动,那么转换时间即是采样周期。
// 2)若通过定时器进行触发启动ADC,则还需要加上定时器的相关时间。
//4)确定采样率
// 1)如果采样率要达到400KHz,为了达到最好的精度,我们选取ADC时钟为12MHz,即6分频。
//在12MHz 以及保证采样率的情况下,采样时间越长其,准确性就越好,每次采样时间为1000000us/400000HZ = 2.5us。
// 2)可以计算 2.5us = (12.5 + 采样时间)/ 12MHz ,可以求得采样时间为17.5;所以采样时间的选择
//必须小于等于17.5个周期,才能保证采样率在400KHz 以上。所以我们可以选择1.5、7.5、13.5,为获得更
//高的精准度,我们可以选择13.5个周期。切记采样点数必须达到要求
volatile u16 ADCConvertedValue[ADCBUF_SIZE];//用来存放ADC转换结果,也是DMA的目标地址
_ADC_UNION ADC_UNION;
u8 BAT_Percent;
u8 Bat_Flag=0;
u8 lowpower;
u8 power_detective;
//设置ADC
void adc1_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_ADC1,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div8);//设置adc时钟分频
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1; //adc输入引脚
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN; //模拟输入
GPIO_Init(GPIOB,&GPIO_InitStructure);
ADC_DeInit(ADC1);//复位ADC1,设为缺省值
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //独立模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE; //数模转换:扫描(多通道)模式=ENABLE 单次(单通道)模式=DISABLE
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //DISABLE单通道模式,enable多通道扫描模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //触发方式 软件
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = 1; //顺序进行规则转换的通道数
ADC_Init(ADC1, &ADC_InitStructure);
//设置指定ADC的规则组通道,设置它们的转化顺序和采样时间
ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 1, ADC_SampleTime_239Cycles5 );
ADC_Cmd(ADC1,ENABLE);
ADC_ResetCalibration(ADC1);//重新指定adc校准寄存器
while(ADC_GetResetCalibrationStatus(ADC1));//获取ADC重置校准寄存器状态
ADC_StartCalibration(ADC1);//开始指定adc校准状态
while(ADC_GetCalibrationStatus(ADC1));//获取指定adc的校准程序
ADC_SoftwareStartConvCmd(ADC1, ENABLE);//使能或者失能指定的ADC的软件转换启动功能
}
//获得 ADC 值
//ch:通道值
u16 Get_Adc(u8 ch)
{
ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能软件转换功能
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束
return ADC_GetConversionValue(ADC1); //返回最近一次 ADC1 规则组的转换结果
}
u16 Get_Adc_Average(u8 ch,u8 times)
{
u32 temp_val=0;
u8 t;
for(t=0;t<times;t++)
{
temp_val+=Get_Adc(ch);
delay_ms(5);
}
return temp_val/times;
}
#ifndef __ADC_H
#define __ADC_H
#include "sys.h"
#define BAT_100 2606 //2606*0.806=2100mV 分压后电压为4200mV
#define BAT_0 1861 //1861*0.806=1500mV 分压后电压为3000mV
#define BAT_LEVEL 746 //总等级746
#define ADCBUF_SIZE 1
extern volatile u16 ADCConvertedValue[ADCBUF_SIZE];//用来存放ADC转换结果,也是DMA的目标地址,3通道,每通道采集10次后面取平均数
typedef union
{
u16 ADC_buf;
u8 adc_buf[2];
}_ADC_UNION;
extern _ADC_UNION ADC_UNION;
extern u8 BAT_Percent;
extern u8 Bat_Flag;
extern u8 lowpower;
extern u8 power_detective;
void adc1_init(void);
u16 Get_Adc(u8 ch);
u16 Get_Adc_Average(u8 ch,u8 times);
#endif
\ No newline at end of file
#include "delay.h"
static u8 fac_us=0; //us延时倍乘数
static u16 fac_ms=0; //ms延时倍乘数,在ucos下,代表每个节拍的ms数
//初始化延迟函数
//SYSTICK的时钟固定为HCLK时钟的1/8
//SYSCLK:系统时钟
void delay_init()
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //选择外部时钟 HCLK/8
fac_us=SystemCoreClock/8000000; //为系统时钟的1/8
fac_ms=(u16)fac_us*1000; //非OS下,代表每个ms需要的systick时钟数
}
//延时nus
//nus为要延时的us数.
void delay_us(u32 nus)
{
u32 temp;
SysTick->LOAD=nus*fac_us; //时间加载
SysTick->VAL=0x00; //清空计数器
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(1<<16))); //等待时间到达
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器
SysTick->VAL =0X00; //清空计数器
}
//延时nms
//注意nms的范围
//SysTick->LOAD为24位寄存器,所以,最大延时为:
//nms<=0xffffff*8*1000/SYSCLK
//SYSCLK单位为Hz,nms单位为ms
//对72M条件下,nms<=1864
void delay_ms(u16 nms)
{
u32 temp;
SysTick->LOAD=(u32)nms*fac_ms; //时间加载(SysTick->LOAD为24bit)
SysTick->VAL =0x00; //清空计数器
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(1<<16))); //等待时间到达
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器
SysTick->VAL =0X00; //清空计数器
}
//延时 S
//最大为18s
void delay_s(u8 s)
{
delay_ms(s*100);//1
delay_ms(s*100);//2
delay_ms(s*100);//3
delay_ms(s*100);//4
delay_ms(s*100);//5
delay_ms(s*100);//6
delay_ms(s*100);//7
delay_ms(s*100);//8
delay_ms(s*100);//9
delay_ms(s*100);//10
}
#ifndef __DELAY_H
#define __DELAY_H
#include "sys.h"
void delay_init(void);
void delay_ms(u16 nms);
void delay_us(u32 nus);
void delay_s(u8 s);
#endif
This diff is collapsed. Click to expand it.
#ifndef __DMA_H
#define __DMA_H
#include "sys.h"
extern u8 UART1_DMA_Finish;
extern u8 UART2_DMA_Finish;
extern u8 UART3_DMA_Finish;
extern u8 UART4_DMA_Finish;
extern u8 SPI1_DMA_TX_Finish;
extern u8 SPI2_DMA_TX_Finish;
extern u8 SPI3_DMA_TX_Finish;
extern u8 ADC_DMA_Finish;
//DMA
void DMA_Config(DMA_Channel_TypeDef* DMA_CHx,u32 cpar,u32 cmar);
void DMA_Enable(DMA_Channel_TypeDef*DMA_CHx,u16 len);
void UART1_DMA_TX_NVIC_Config(u8 cmd);
void UART2_DMA_TX_NVIC_Config(u8 cmd);
void UART3_DMA_TX_NVIC_Config(u8 cmd);
void UART4_DMA_TX_NVIC_Config(u8 cmd);
//ADC
void ADC_DMA_Config(u16 *buffer ,u16 len);
void ADC_DMA_Enable(void);
//SPI1 DMA
u8 SPI1_DMA_Config(void);
u8 SPI2_DMA_Config(void);
u8 SPI3_DMA_Config(void);
void SPI1_DMA_NVIC_Config(u8 cmd);
void SPI2_DMA_NVIC_Config(u8 cmd);
void SPI3_DMA_NVIC_Config(u8 cmd);
u8 SPI1_DMA_RX(u8 *buffer,u16 len);
u8 SPI2_DMA_RX(u8 *buffer,u16 len);
u8 SPI3_DMA_RX(u8 *buffer,u16 len);
u8 SPI1_DMA_TX(u8 *buffer,u16 len);
u8 SPI2_DMA_TX(u8 *buffer,u16 len);
u8 SPI3_DMA_TX(u8 *buffer,u16 len);
#endif
/* Define to prevent recursive inclusion ----------------------------*/
#ifndef __FATFS_H
#define __FATFS_H
/* Includes == 文件包含 --------------------------------------------*/
#include "sys.h"
#include "ff.h"
#include "diskio.h"
#define FONT_ADDR "0:/SYSTEM/GBK16.FON" //字库文件路径
void FATFS_Get_HzMat(u8 *font, u8 *dzk, u8 size);
/* Private typedef == 私有类型 ----------------------------------*/
/* Private define == 私有定义 ----------------------------------*/
#define FATFS_MAX_FILE_NUM 200 //一个目录下最多文件及文件夹数
#define FATFS_MAX_LAYER_NUM 10 //文件目录最多嵌套层数
#define FATFS_MAX_FILE_PATH_NAME 250 //一个文件路径的最多长度, 如 /mp3/song/chiansong/吻别.MP3
#define FATFS_MAX_FILE_NAME_TOTAL 2048 //一个目录所有文件名及文件夹名的总长度
//-----------------------------------------//
typedef struct
{
//-------------------------------------//
//当前目录下的文件大概信息
u8 FileQuantity; //当前目录下的总文件数
u8 FileNameBuff[FATFS_MAX_FILE_NAME_TOTAL]; //当前目录的全部文件名存放缓存,每个文件名以'\0'结束
u32 FileNameLen; //当前目录全部文件名的总长度
//-------------------------------------//
//当前目录信息
u8 FilePathName[FATFS_MAX_FILE_PATH_NAME]; //当前路径名
u8 FilePathLen; //当前路径名长度
u8 FileCurNum; //当前被选中的文件编号
//-------------------------------------//
//当前目录下的文件具体信息
u8 FileLen[FATFS_MAX_FILE_NUM]; //表示第N个文件名的长度
u8 FileType[FATFS_MAX_FILE_NUM]; //表示第N个文件的类型
u32 FilePostion[FATFS_MAX_FILE_NUM]; //表示第N个文件名存放在FileNameBuff的位置
u8 FileSongPos[FATFS_MAX_FILE_NUM]; //当前目录下的可播放歌曲相对于总可播放歌曲的位置
//-------------------------------------//
//目录嵌套层信息
u8 FileLayerTol; //文件路径层数
u8 FileLayerNum[FATFS_MAX_LAYER_NUM]; //文件路径每一层的被选中的文件编号
//-------------------------------------//
//当前目录可播放歌曲信息
u8 FileCurSongNum; //当前音乐的编号
u8 FileSongAll; //当前目录下的可播放歌曲总数
u8 FileSongNum[FATFS_MAX_FILE_NUM]; //当前目录下的可播放歌曲相对于总文件目录的位置
}FATFS_FileListInfoTypeDef;
#define FATFS_FILEISDIR 0x01
#define FATFS_FILEISMP3 0x02
#define FATFS_FILEISWMA 0x03
#define FATFS_FILEISWAV 0x04
#define FATFS_FILEISFLAC 0x05
#define FATFS_FILEISOTHER 0x06
/* Private macro == 私有宏 ------------------------------------*/
/* Private variables == 私有变量 ----------------------------------*/
/* Private function prototypes == 私有函数声明 --------------------*/
void FATFS_Die(FRESULT rc);
void FATFS_GetChinaDocData(u8 *buff, u8 size, u8 *china);
void FATFS_FileSacn(u8 *path, FATFS_FileListInfoTypeDef *filelist);
void FATFS_DisplayFileName(FATFS_FileListInfoTypeDef *list);
void FATFS_DisplayFileNameBefore(FATFS_FileListInfoTypeDef *list);
void FATFS_DisplayFileNameNext(FATFS_FileListInfoTypeDef *list);
void FATFS_DisplayFileNameBack(FATFS_FileListInfoTypeDef *list);
void FATFS_DisplayFileNameMove(FATFS_FileListInfoTypeDef *list);
/* Define to prevent recursive inclusion ----------------------------*/
#endif /* __FATFS_H */
/********************************* (C) COPYRIGHT 2014 waft_wind ********* END OF FILE **********************************/
#include "hc05.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "key.h"
//蓝牙引脚初始化
void HCO5_IO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
//AT B7 EN B9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9| GPIO_Pin_7; //HC05-EN
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
HC05_OFF;//关蓝牙
HC05_AT=0; //取消AT指令
}
u8 HC05_SET_FLAG=0;
//蓝牙设置检测
void HC05_SET(void)
{
u16 ret=0;
if (KEYPWR == 0)//按键按下
{
LED_2=LED_ON;
while( KEYPWR == 0)
{
delay_ms(10);
ret++;
if ( ret > 300 )//3s
{
LED_2=LED_OFF;
HC05_SET_FLAG=1;//设置蓝牙
while( KEYPWR == 0);
return ;//退出函数
}
}
LED_2=LED_OFF;
}
}
//发送指令,并判断指定字符串是否缓冲区中
//返回-1 没有指定的串
//0-125 字符串在数组中的位置
s16 HC05_SendCmd(u8* cmd, u8* result, u16 timeOut)
{
s16 res;
HC05_CLEAR();//清空缓冲区
USARTx_Send(HC05_UART,(uint8_t*) cmd, strlen(cmd));
delay_ms(timeOut);
HC05_DEBUG("HC05 rsp:%s \r\n",HC05_RX_BUF);
res = Str_search(HC05_RX_BUF,HC05_RX_LEN,result);//查询字符串
return res;
}
u8 HCO5_AT_Confg(void)
{
u8 res=1;
//设置AT模式
HC05_AT=1; //拉高AT引脚
delay_s(1);
HC05_ON;//开蓝牙
delay_s(1);
HC05_AT=0;
delay_s(1);
HC05_uart_init(38400);
USART_ITConfig(HC05_UART, USART_IT_RXNE, ENABLE);//开启串口接受中断
HC05_DEBUG("AT测试 ");
if(HC05_SendCmd(HC05_AT_TEST, "OK", 500) < 0)//通讯测试
goto end;
LED_2 =!LED_2;
HC05_DEBUG("成功\r\n");
HC05_DEBUG("设置蓝牙名 ");
if(HC05_SendCmd(HC05_AT_NAME, "OK", 500) < 0)//名称
goto end;
LED_2 =!LED_2;
HC05_DEBUG("成功\r\n");
HC05_DEBUG("清除记录的地址 ");
if(HC05_SendCmd(HC05_AT_RMAAD, "OK", 500) < 0)//清除从机地址
goto end;
LED_2 =!LED_2;
HC05_DEBUG("成功\r\n");
HC05_DEBUG("设置波特率 ");
if(HC05_SendCmd(HC05_AT_UART, "OK", 500) < 0) //设置波特率
goto end;
LED_2 =!LED_2;
HC05_DEBUG("成功\r\n");
HC05_DEBUG("设置连接方式 ");
if(HC05_SendCmd(HC05_AT_CMODE, "OK", 500) < 0)//连接方式
goto end;
LED_2 =!LED_2;
HC05_DEBUG("成功\r\n");
HC05_DEBUG("设置密码 ");
if(HC05_SendCmd(HC05_AT_PSWD, "OK", 500) < 0) //设置密码
goto end;
LED_2 =!LED_2;
HC05_DEBUG("成功\r\n");
HC05_DEBUG("主从设置 ");
if(HC05_SendCmd(HC05_AT_RLOE, "OK", 500) < 0)//主从模式
goto end;
LED_2 =!LED_2;
HC05_DEBUG("成功\r\n");
HC05_DEBUG("复位 ");
HC05_SendCmd(HC05_AT_RESET, "OK", 500);//复位
res=0;//设置成功
end:
USART_ITConfig(HC05_UART, USART_IT_RXNE, DISABLE);//关闭串口接受中断
LED_2=LED_OFF;
HC05_OFF;//关蓝牙电源
if(res == 0)
HC05_DEBUG("蓝牙设置成功\r\n");
else
HC05_DEBUG("蓝牙设置失败\r\n");
HC05_OFF;//关蓝牙电源
return res;
}
#ifndef __HC05_H
#define __HC05_H
#include "sys.h"
#define HC05_UART_DEBUG 1 //串口调试开关
#define HC05_AT PBout(7) //AT控制引脚
#define HC05_EN PBout(9) //电源控制引脚
#define HC05_ON HC05_EN=0
#define HC05_OFF HC05_EN=1
#define HC05_UART USART3
#define HC05_uart_init(x) uart3_init(x)
#define HC05_RX_LEN USART3_RX_LEN
#define HC05_RX_BUF USART3_RX_BUF
#define HC05_CLEAR() USART3_Clear()
////////////////////////////////////////////////////////////////////////////////
//串口DEBUG
#if HC05_UART_DEBUG == 1
#define HC05_DEBUG(...) Main_printf(__VA_ARGS__)
#else
#define HC05_DEBUG(...)
#endif
#define HC05_AT_TEST "AT\r\n" //AT测试
#define HC05_AT_NAME "AT+NAME=HC05\r\n" //设置设备名称
//#define HC05_AT_RLOE "AT+ROLE=1\r\n" //设置为主机
#define HC05_AT_RLOE "AT+ROLE=0\r\n" //设置为从机 从机可以被手机和电脑搜索到
#define HC05_AT_RMAAD "AT+RMAAD\r\n" //清除主机记录的从机地址
//#define HC05_AT_PSWD "AT+PSWD=1234\r\n" //蓝牙密码
#define HC05_AT_PSWD "AT+PSWD=\"1234\"\r\n" //蓝牙密码 兼容芯片
#define HC05_AT_UART "AT+UART=460800,0,0\r\n" //设置波特率
#define HC05_AT_CMODE "AT+CMODE=1\r\n" //设置连接方式
#define HC05_AT_RESET "AT+RESET\r\n" //复位
extern u8 HC05_SET_FLAG;//蓝牙设置标志
void HCO5_IO_Init(void);//上电引脚初始化
u8 HCO5_AT_Confg(void); //设置蓝牙
void HC05_SET(void);
u8 Blue_Uart_Send(u8 *p); //串口设置函数
#endif
#include "key.h"
#include "delay.h"
#include "led.h"
#include "usart.h"
#include "Timer.h"
#include "ADS129x.h"
//按键及电源控制初始化
void KEY_Init(void) //IO初始化
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能PORTA,PORTE时钟
//PWR_CTRL A4
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//KEY PWR A1
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉输入
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void KE_IO_Init(void) //拨码开关
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE);//使能PORTA,PORTE时钟
//KE 1 2 3 4
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11|GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_5;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
//开机检测
u8 Power_ON(void)
{
u8 ret=0;
if (KEYPWR == 0)//按键按下
{
LED1=LED_ON;//使能供电
while( KEYPWR == 0)
{
delay_ms(10);
ret++;
if ( ret > 150 )//1.5s
{
POWER_ON;
LED2=LED_ON;
while( KEYPWR == 0);
LED2=LED_OFF;
return 0;//开机成功
}
}
delay_ms(100);
LED1=LED_OFF;
}
return 1; //开机失败
}
volatile u8 KEY_TYPE=0;//按键标志
volatile u8 KEY_STATE=0;//按键状态
volatile u8 KEY_Mark=0;//标记
void Key_Scan(void)
{
//按键没按下过
if(TIM2_FLAG==0 && KEY_STATE==0 && KEYPWR==0)
{
TIM_Cmd(TIM2, ENABLE);
if(KEYPWR == 0)
{
LED_2=LED_ON;
KEY_STATE |= KEY_PWR;
}
}
}
void Change_Mode(void)
{
if(KEY_TYPE)
{
//__disable_irq();
delay_s(2);
LED_2=LED_OFF;
if(KEY_TYPE == KEY_PWR)
{
EXTI->IMR &= ~(ADS129X_DRDY_LINE);//屏蔽外部中断
work_state++;
if(work_state == 4)
work_state=1;
//printf("切换工作模式\r\n");
}
KEY_TYPE=0;
}
}
//void Key_Scan(void)
//{
// if ( KEY1 == 0 )//KEY1按下
// {
// if(KeyDat & 0x01)//检查按键按下标志位
// {
// if(TIM3->CNT >= KEYDOWNMINTIME)//延时大于1s(按键有效)
// {
// if(TIM3->CNT >= KEYDOWNLONGTIME)//延时大于2s(长按键)
// {
// KeyMask=KEYLONGDOWN;
// }
// else//短按键事件
// {
// KeyMask=KEYSHORTDOWN;
// }
// DS2=0;//按键有效
// }
// }
// else//按键按下瞬间
// {
// TIM_Cmd(TIM3, ENABLE); //使能TIM
// printf("按键1按下\r\n");
//
// DS2=0;//按键按下瞬间
//
// KeyDat |= 0x01; //首次按键标记
// KeyMask=KEYUNKNOW ;//瞬间按下为无效状态
// }
// }
// else//无按下按下,或者按键弹起
// {
// if(KeyDat & 0x01) //按键按下后弹起
// {
// KeyDat &= ~0x01;//清按键标志
// TIM_Cmd(TIM3, DISABLE);//关定时器
// TIM3->CNT=0;//清空定时器计数器
//
//
// if(KeyMask==KEYSHORTDOWN )//短按键事件
// {
// KeyMask=KEYUNKNOW;//清变量
// printf("短按键\r\n");
// }
// else if(KeyMask==KEYLONGDOWN)//长按键事件
// {
// KeyMask=KEYUNKNOW;//清变量
// printf("长按键\r\n");
//
// }
//
// }
// }
//}
#ifndef __KEY_H
#define __KEY_H
#include "sys.h"
#define USE_BUZZER 0
#define POWER_CTRL PAout(4)
#define KEYPWR PAin(1)
#define KE_1 PBin(8)
#define KE_2 PBin(5)
#define KE_3 PAin(11)
#define KE_4 PAin(8)
#define KEY_1 0x01
#define KEY_2 0x02
#define KEY_PWR 0x04
#define POWER_ON POWER_CTRL=1
#define POWER_OFF POWER_CTRL=0
#define KEYDOWNMINTIME 10000 //短按键时间1s
#define KEYDOWNLONGTIME 30000 //长按键3s
#define KEYUNKNOW 0 //按键状态
#define KEYSHORTDOWN 1
#define KEYLONGDOWN 2
extern volatile u8 KEY_TYPE;//按键标志
extern volatile u8 KEY_STATE;//按键状态
extern volatile u8 KEY_Mark;//标记
u8 Power_ON(void); //按键开机检测
void KEY_Init(void);
void KEY_NVIV_Init(void); //中断初始化
void Key_Scan(void);
void Change_Mode(void);
void KE_IO_Init(); //拨码开关
#endif
#include "led.h"
//LED IO初始化
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE); //使能PB端口时钟
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
// 对PA13引脚进行重映射:
// GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; //IO口速度为2MHz
GPIO_Init(GPIOB, &GPIO_InitStructure);
LED1 =LED_OFF;
LED2 =LED_OFF;
}
//由上图可知,重映射的方式一共有三种。分别描述如下:
//1.GPIO_Remap_SWJ_JTAGDisable: /*!< JTAG-DP Disabled and SW-DP Enabled */ 即能用PB3,PB4,PA15做普通IO,PA13&14用于SWD调试
//2.GPIO_Remap_SWJ_Disable: /*!< Full SWJ Disabled (JTAG-DP + SW-DP) */ 5个引脚全为普通引脚,但不能再用JTAG&SWD仿真器调试,只能用st-link调试
//3.GPIO_Remap_SWJ_NoJTRST: /*!< Full SWJ Enabled (JTAG-DP + SW-DP) but without JTRST */PB4可为普通IO口,JTAG&SWD正常使用,但JTAG没有复位
//如果你用到所有的五个引脚当做普通IO口,那么上述步骤二中的重映射配置应写为GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE);
//如果你用PB3,PB4,PA15做普通IO,PA13&14用于SWD调试,则重映射配置应写为GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
//同理可配置只用PB4可为普通IO口的情况。
\ No newline at end of file
#ifndef __LED_H
#define __LED_H
#include "sys.h"
#define LED1 PBout(3)
#define LED2 PBout(4)
#define DS1 LED1
#define DS2 LED2
#define LED_1 LED1
#define LED_2 LED2
#define LED_ON 0
#define LED_OFF 1
void LED_Init(void);//³õʼ»¯
#endif
#include "malloc.h"
//内存池(4字节对齐)
__align(4) u8 membase[MEM_MAX_SIZE]; //内部SRAM内存池 [最大管理内存]
//内存管理表
u16 memmapbase[MEM_ALLOC_TABLE_SIZE]; //内部SRAM内存池MAP
//内存管理参数
const u32 memtblsize=MEM_ALLOC_TABLE_SIZE; //内存表大小
const u32 memblksize=MEM_BLOCK_SIZE; //内存分块大小
const u32 memsize=MEM_MAX_SIZE; //内存总大小
//内存管理控制器
struct _m_mallco_dev mallco_dev=
{
mem_init, //内存初始化
mem_perused, //内存使用率
membase, //内存池
memmapbase, //内存管理状态表
0, //内存管理未就绪
};
//复制内存
//*des:目的地址
//*src:源地址
//n:需要复制的内存长度(字节为单位)
void mymemcpy(void *des,void *src,u32 n)
{
u8 *xdes=des;
u8 *xsrc=src;
while(n--)*xdes++=*xsrc++;
}
//设置内存
//*s:内存首地址
//c :要设置的值
//count:需要设置的内存大小(字节为单位)
void mymemset(void *s,u8 c,u32 count)
{
u8 *xs = s;
while(count--)*xs++=c;
}
//内存管理初始化
void mem_init(void)
{
mymemset(mallco_dev.memmap, 0,memtblsize*2);//内存状态表数据清零
mymemset(mallco_dev.membase, 0,memsize); //内存池所有数据清零
mallco_dev.memrdy=1; //内存管理初始化OK
}
//获取内存使用率
//返回值:使用率(0~100)
u8 mem_perused(void)
{
u32 used=0;
u32 i;
for(i=0;i<memtblsize;i++)
{
if(mallco_dev.memmap[i])used++;
}
return (used*100)/(memtblsize);
}
//内存分配(内部调用)
//memx:所属内存块
//size:要分配的内存大小(字节)
//返回值:0XFFFFFFFF,代表错误;其他,内存偏移地址
u32 mem_malloc(u32 size)
{
signed long offset=0;
u16 nmemb; //需要的内存块数
u16 cmemb=0;//连续空内存块数
u32 i;
if(!mallco_dev.memrdy)mallco_dev.init(); //未初始化,先执行初始化
if(size==0)return 0XFFFFFFFF; //不需要分配
nmemb=size/memblksize; //获取需要分配的连续内存块数
if(size%memblksize)nmemb++;
for(offset=memtblsize-1;offset>=0;offset--) //搜索整个内存控制区
{
if(!mallco_dev.memmap[offset])cmemb++; //连续空内存块数增加
else cmemb=0; //连续内存块清零
if(cmemb==nmemb) //找到了连续nmemb个空内存块
{
for(i=0;i<nmemb;i++) //标注内存块非空
{
mallco_dev.memmap[offset+i]=nmemb;
}
return (offset*memblksize); //返回偏移地址
}
}
return 0XFFFFFFFF;//未找到符合分配条件的内存块
}
//释放内存(内部调用)
//offset:内存地址偏移
//返回值:0,释放成功;1,释放失败;
u8 mem_free(u32 offset)
{
int i;
if(!mallco_dev.memrdy)//未初始化,先执行初始化
{
mallco_dev.init();
return 1;//未初始化
}
if(offset<memsize)//偏移在内存池内.
{
int index=offset/memblksize; //偏移所在内存块号码
int nmemb=mallco_dev.memmap[index]; //内存块数量
for(i=0;i<nmemb;i++) //内存块清零
{
mallco_dev.memmap[index+i]=0;
}
return 0;
}else return 2;//偏移超区了.
}
//释放内存(外部调用)
//ptr:内存首地址
void myfree(void *ptr)
{
u32 offset;
if(ptr==NULL)return;//地址为0.
offset=(u32)ptr-(u32)mallco_dev.membase;
mem_free(offset); //释放内存
}
//分配内存(外部调用)
//size:内存大小(字节)
//返回值:分配到的内存首地址.
void *mymalloc(u32 size)
{
u32 offset;
offset=mem_malloc(size);
if(offset==0XFFFFFFFF)return NULL;
else return (void*)((u32)mallco_dev.membase+offset);
}
//重新分配内存(外部调用)
//*ptr:旧内存首地址
//size:要分配的内存大小(字节)
//返回值:新分配到的内存首地址.
void *myrealloc(void *ptr,u32 size)
{
u32 offset;
offset=mem_malloc(size);
if(offset==0XFFFFFFFF)return NULL;
else
{
mymemcpy((void*)((u32)mallco_dev.membase+offset),ptr,size); //拷贝旧内存内容到新内存
myfree(ptr); //释放旧内存
return (void*)((u32)mallco_dev.membase+offset); //返回新内存首地址
}
}
/*
void * 的作用
  C语言中void * 为 “不确定类型指针”,void *可以用来声明指针。如:void * a;
  (1)void *可以接受任何类型的赋值:
    void *a = NULL;
    int * b = NULL;
    a = b;//a是void * 型指针,任何类型的指针都可以直接赋值给它,无需进行强制类型转换
  
(2)void *可以赋值给任何类型的变量 但是需要进行强制转换:
    int * a = NULL ;
   void * b ;
    a = (int *)b;
   但是有意思的是:void* 在转换为其他数据类型时,赋值给void* 的类型 和目标类型必须保持一致。简单点来说:void* 类型接受了int * 的赋值后 这个void * 不能转化为其他类型,必须转换为int *类型;
*/
#ifndef __MALLOC_H
#define __MALLOC_H
#include "sys.h"
#ifndef NULL
#define NULL 0
#endif
//C8T6
// FLASH 64K 中容量
// SRAM 20K
//ZET6
// FLASH 512K 大容量
// SRAM 64K
//定义两个内存池
#define SRAMIN 0 //内部内存池
#define SRAMEX 1 //外部内存池
#define SRAMBANK 2 //定义支持的SRAM块数.
//内存参数设定.
#define MEM_BLOCK_SIZE 32 //内存块大小为32字节
#define MEM_MAX_SIZE 12*1024 //最大管理内存
#define MEM_ALLOC_TABLE_SIZE MEM_MAX_SIZE/MEM_BLOCK_SIZE //内存表大小
//内存管理控制器
struct _m_mallco_dev
{
void (*init)(void); //初始化
u8 (*perused)(void); //内存使用率
u8 *membase; //内存池
u16 *memmap; //内存管理状态表
u8 memrdy; //内存管理是否就绪
};
extern struct _m_mallco_dev mallco_dev; //在mallco.c里面定义
void mymemset(void *s,u8 c,u32 count); //设置内存
void mymemcpy(void *des,void *src,u32 n);//复制内存
void mem_init(void); //内存管理初始化函数(外/内部调用)
u32 mem_malloc(u32 size); //内存分配(内部调用)
u8 mem_free(u32 offset); //内存释放(内部调用)
u8 mem_perused(void); //得内存使用率(外/内部调用)
////////////////////////////////////////////////////////////////////////////////
//用户调用函数
void myfree(void *ptr); //内存释放(外部调用)
void *mymalloc(u32 size); //内存分配(外部调用)
void *myrealloc(void *ptr,u32 size); //重新分配内存(外部调用)
#endif
#include "myQueue.h"
#include "malloc.h"
#include <string.h>
#include "usart.h"
/////////////////////////////////////////////////////////////////////////////////////////////
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//红茶电子科技-红茶
//淘宝 https://shop119364888.taobao.com
//创建日期:2021/02/01
//版本:V1.0
//版权所有,盗版必究。
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
//QueueInfo存储当前队列的一些信息,
//data为动态申请的连续的队列空间,
//front指向队列头,
//rear为队列尾部,
//capacity为队列可容纳的大小。
/////////////////////////////////////////////////////////////////////////////////////////////
//其中使用QueueInfo存储当前队列的一些信息,data为动态申请的连续的队列空间,
//front指向队列头,rear为队列尾部,capacity为队列可容纳的大小。初始化时,
//将front与rear都置为0。由于是循环使用队列空间,当逐渐入队capacity个元素时,
//此时front超过了队列容量,需要将其重置到0位置,这样将无法判断当前队列是满还是空。
//一种解决办法是,仅使用capacity-1个空间进行存储,始终保持front与rear之间存在
//不小于1个可用空间,此方法与链表的头节点有异曲同工之妙。
/* Recyle Queue Operator Push and Pop Sketch
* Queue Size: 4
* Capacity : 7
* front rear front rear rear front
* | | | | | |
* 1 2 3 4[ ][ ][ ] [ ]1 2 3 4[ ][ ] 4[ ][ ][ ]1 2 3
* (1) (2) (3)
*
* PUSH : 5 放入5
* front rear front rear rear front
* | | | | | |
* 1 2 3 4 5[ ][ ] [ ]1 2 3 4 5[ ] 4 5[ ][ ]1 2 3
* (1+) (2+) (3+)
*
* POP : 取出
* front rear front rear rear front
* | | | | | |
* [ ]2 3 4[ ][ ][ ] [ ][ ]2 3 4[ ][ ] 4[ ][ ][ ][ ]2 3
* (1-) (2-) (3-)
* */
//对于同样容量为7,大小为4的循环队列,有以上三种情况。所以当判断队列是否为空、
//或者是否有可用空间时,切勿直接判断front与rear的大小。因此,当进行入队和出队时,
//也要针对不同情况进行处理。每次入队时,将元素覆盖在rear处,并将rear后移一位,
//注意判断队列为空还是满,并且保证其不大于capacity。出队则从队头删除,只需将front向后移动即可。
/////////////////////////////////////////////////////////////////////////////////////////////
//循环队列初始化 容量 长度
QueueInfo *queue_init(u32 size,u32 length)//循环队列初始化
{
u32 i;
QueueInfo *q;
u8 res=0;
if (size == 0) return NULL;
q = (QueueInfo*)mymalloc(sizeof(QueueInfo)); //队列结构
if(q == NULL) return NULL; //内存申请失败
q->carry_num=0;//搬运计数
q->length = length; //队列容量
q->front = q->rear = 0; //初始化时,将front与rear都置为0。
q->capacity = size; //队列大小
q->databuf = (u8 **)mymalloc( q->capacity *4);//申请动态内存空间,队列容量 32位单片机,指针占用4字节空间
if(q->databuf == NULL)
{
myfree(q);//释放内存
return NULL; //内存申请失败
}
for(i=0;i<q->capacity;i++) //队列容量
{
*(q->databuf+i) = (u8*)mymalloc(q->length); //申请 n 个大小为 length 的数组
if(*(q->databuf+i) == NULL)
{
res=1;
break;
}
memset( *(q->databuf + i),0,length);//清0
//Main_printf(" (q->databuf)+%d %x ",i, ((q->databuf)+i) ); //指针数组 指针是32位的
//Main_printf("*((q->databuf)+%d) %x ",i, *((q->databuf)+i) ); //数组指向的地址
}
if(res)//内存申请失败
{
while(i)
{
myfree(*(q->databuf+i));
i--;
}
myfree(q->databuf);//释放内存
myfree(q);//释放内存
return NULL;
}
return q;//返回初始化的队列指针
}
u8 queue_Deinit(QueueInfo *q)//循环队列注销
{
u16 i;
if(q==NULL) return 1; //指针无效
for(i=0;i<q->capacity;i++)
{
myfree(*(q->databuf+i));//释放内存
}
myfree(q->databuf);//释放内存
myfree(q);//释放内存
return 0;
}
//数组的前端添加项
//每次入队时,将元素覆盖在rear处,并将rear后移一位,
//注意判断队列为空还是满,并且保证其不大于capacity。
s8 queue_push(QueueInfo *q, u8 *cache,u8 length)
{
u16 i;
if (q==NULL) return -1; // need queue
if ((q->rear+1) % q->capacity == q->front) //队列满了
{
q->front = (q->front+1) % q->capacity;//队头自增,删除最先进入的数据
//return 0;//满了
}
memcpy( *(q->databuf + q->rear),cache,length);//搬运 N 个字节
q->rear = (q->rear+1) % q->capacity; //取数据,队头自增,存数据,队尾自增
return 1; // return push count
}
//从数组的后端移除项
//队列取数据
s8 queue_pop(QueueInfo *q,u8 *sendbuf,u16 length)//从队列搬运 n个字节 至发送缓冲区
{
if (q==NULL) return -1; // need queue
if (q->front==q->rear) return 0;//队列为空
memcpy(sendbuf,*(q->databuf + q->front),length);//copy n 个字节
q->front = (q->front+1) % q->capacity;//取数据,队头自增,存数据,队尾自增
return 1; //取到数据
}
//检测队列是否有数据
//1 有数据 0 没有数据
s8 serch_queue_data(QueueInfo *q)
{
if (q==NULL) return -1; //need queue
if (q->front==q->rear) return 0;//队列为空
else return 1;//有数据
}
//队列清空
s8 queue_clear(QueueInfo *q)
{
u16 i;
if(q == NULL) return -1; //need queue
q->carry_num=0;
q->front = q->rear = 0; //初始化时,将front与rear都置为0。
for(i=0;i<q->capacity;i++) //队列容量
{
memset( *(q->databuf + i),0,q->length);//清0
}
return 1;
}
//队列的插入,顺次向队列缓存区搬运数据
//参数:队列指针,数据来源,要搬运的数据长度,要搬运的次数
s8 queue_data_push(QueueInfo *q, u8 *cache,u8 length,u16 times)
{
u16 i;
if (q==NULL) return -1; // need queue
if ((q->rear+1) % q->capacity == q->front) //队列满了
{
q->front = (q->front+1) % q->capacity;//队头自增,删除最先进入的数据
q->Queue_Full_flag=1;
//Main_printf("m");
//return 0;//满了
}
else
{
//q->Queue_Full_flag=0;
}
memcpy( *(q->databuf + q->rear)+ q->carry_num *length,cache,length);//搬运 length 个字节
q->carry_num++;//数据搬运次数计数
if(q->carry_num == times) //搬运N次数据
{
q->carry_num=0;
q->rear = (q->rear+1) % q->capacity; //取数据,队头自增,存数据,队尾自增
return 1; //搬运完成一帧数据
}
else
return 0;
}
#ifndef __myQueue_H
#define __myQueue_H
#include "sys.h"
//push()方法可以在数组的末属添加一个或多个元素
//shift()方法把数组中的第一个元素删除
//unshift()方法可以在数组的前端添加一个或多个元素
//pop()方法把数组中的最后一个元素删除
//循环队列 结构体声明
__align(4) typedef struct {
u8 Queue_Full_flag;
u8 Queue_data_state; //数据状态
u32 front, rear; //front指向队列头,rear为队列尾部
u32 capacity,length; //队列大小,容量
//capacity 队列容量 (队列缓冲区数量)
//length 队列长度/大小 (缓存的数据长度)
u16 carry_num; //数据搬运次数,n次打包
u8 **databuf; //二级指针 动态内存申请
}QueueInfo;
/////////////////////////////////////////////////////////////////////
//外部函数
QueueInfo *queue_init(u32 size,u32 length);//循环队列初始化
u8 queue_Deinit(QueueInfo *q);//循环队列注销
s8 queue_push(QueueInfo *q, u8 *cache,u8 length) ;//数据放入队列
s8 queue_pop(QueueInfo *q,u8 *sendbuf,u16 length);//从队列搬运 n个字节 至发送缓冲区
s8 queue_clear(QueueInfo *q);//从队列搬运 n个字节 至发送缓冲区
s8 serch_queue_data(QueueInfo *q);//检测队列是否有数据
s8 queue_data_push(QueueInfo *q, u8 *cache,u8 length,u16 times);//队列插入数据
#endif
\ No newline at end of file
This diff is collapsed. Click to expand it.
#ifndef __RTC_H
#define __RTC_H
//Mini STM32开发板
//RTC实时时钟 驱动代码
//正点原子@ALIENTEK
//2010/6/6
//时间结构体
typedef struct
{
vu8 hour;
vu8 min;
vu8 sec;
//公历日月年周
vu16 w_year;
vu8 w_month;
vu8 w_date;
vu8 week;
}_calendar_obj;
extern _calendar_obj calendar; //日历结构体
//extern u8 const mon_table[12]; //月份日期数据表
extern u8 year[],month[],day[],hour[],min[],second[];//储存时间
extern u8 RCTtime[15];
extern u8 RTC_IRQH_FLAG;//1秒中断
void Disp_Time(u8 x,u8 y,u8 size);//在制定位置开始显示时间
void Disp_Week(u8 x,u8 y,u8 size,u8 lang);//在指定位置显示星期
u8 RTC_Init(void); //初始化RTC,返回0,失败;1,成功;
u8 Is_Leap_Year(u16 year);//平年,闰年判断
u8 RTC_Alarm_Set(u16 syear,u8 smon,u8 sday,u8 hour,u8 min,u8 sec);
u8 RTC_Get(void); //更新时间
u8 RTC_Get_Week(u16 year,u8 month,u8 day);
u8 RTC_Set(u16 syear,u8 smon,u8 sday,u8 hour,u8 min,u8 sec);//设置时间
u8 *GET_RTC_TIME( u8 year[4],u8 month[2],u8 day[2],u8 hour[2],u8 min[2],u8 second[2],u8 CMD);
//u8 *GET_RTC_TO_BUF(void);
void Num_To_Ascii(u16 num,u8 len,u8 *buf);
u8 *Creat_File(void);//创建文件名
#endif
#ifndef _MMC_SD_H_
#define _MMC_SD_H_
#include "sys.h"
#define USE_SPI1 0 //如果使能SPI1
#define USE_SPI2 1 //如果使能SPI2
#define USE_SPI3 0 //如果使能SPI3
#define EN_SPI_Tx_DMA 0 //如果使能SPI发送的DMA
#define EN_SPI_Rx_DMA 0 //如果使能SPI接收的DMA
// SD卡类型定义
#define SD_TYPE_ERR 0X00
#define SD_TYPE_MMC 0X01
#define SD_TYPE_V1 0X02
#define SD_TYPE_V2 0X04
#define SD_TYPE_V2HC 0X06
// SD卡指令表
#define CMD0 0 //卡复位
#define CMD1 1
#define CMD8 8 //命令8 ,SEND_IF_COND
#define CMD9 9 //命令9 ,读CSD数据
#define CMD10 10 //命令10,读CID数据
#define CMD12 12 //命令12,停止数据传输
#define CMD16 16 //命令16,设置SectorSize 应返回0x00
#define CMD17 17 //命令17,读sector
#define CMD18 18 //命令18,读Multi sector
#define CMD23 23 //命令23,设置多sector写入前预先擦除N个block
#define CMD24 24 //命令24,写sector
#define CMD25 25 //命令25,写Multi sector
#define CMD41 41 //命令41,应返回0x00
#define CMD55 55 //命令55,应返回0x01
#define CMD58 58 //命令58,读OCR信息
#define CMD59 59 //命令59,使能/禁止CRC,应返回0x00
//数据写入回应字意义
#define MSD_DATA_OK 0x05
#define MSD_DATA_CRC_ERROR 0x0B
#define MSD_DATA_WRITE_ERROR 0x0D
#define MSD_DATA_OTHER_ERROR 0xFF
//SD卡回应标记字
#define MSD_RESPONSE_NO_ERROR 0x00
#define MSD_IN_IDLE_STATE 0x01
#define MSD_ERASE_RESET 0x02
#define MSD_ILLEGAL_COMMAND 0x04
#define MSD_COM_CRC_ERROR 0x08
#define MSD_ERASE_SEQUENCE_ERROR 0x10
#define MSD_ADDRESS_ERROR 0x20
#define MSD_PARAMETER_ERROR 0x40
#define MSD_RESPONSE_FAILURE 0xFF
//这部分应根据具体的连线来修改!
#define SD_CS PBout(12) //SD卡片选引脚
extern u8 SD_Type;//SD卡的类型
//函数申明区
u8 SD_SPI_ReadWriteByte(u8 data);
void SD_SPI_SpeedLow(void);
void SD_SPI_SpeedHigh(void);
u8 SD_WaitReady(void); //等待SD卡准备
u8 SD_GetResponse(u8 Response); //获得相应
u8 SD_Initialize(void); //初始化
u8 SD_ReadDisk(u8*buf,u32 sector,u8 cnt); //读块
u8 SD_WriteDisk(u8*buf,u32 sector,u8 cnt); //写块
u32 SD_GetSectorCount(void); //读扇区数
u8 SD_GetCID(u8 *cid_data); //读SD卡CID
u8 SD_GetCSD(u8 *csd_data); //读SD卡CSD
void SD_Read_Sectorx(u32 sec);
#endif
#include "spi.h"
#include "delay.h"
//129x SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
//TF SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
void SPI1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_SPI1, ENABLE);
//SCK PA5 //MISO PA6 //MOSI PA7
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化串口输入
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //设置SPI工作模式:设置为主SPI
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //设置SPI的数据大小:SPI发送接收8位帧结构
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //SCLK空闲为低,上升沿锁存数据
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //串行同步时钟的第二个跳变沿(上升或下降)数据被采样
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; //定义波特率预分频的值:波特率预分频值为256
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式
SPI_Init(SPI1,&SPI_InitStructure);
SPI_Cmd(SPI1,ENABLE); //使能SPI外设
}
//SPI 速度设置函数
//SPI_BaudRatePrescaler_2 2分频 (SPI 36M@sys 72M)
//SPI_BaudRatePrescaler_8 8分频 (SPI 9M@sys 72M)
//SPI_BaudRatePrescaler_16 16分频 (SPI 4.5M@sys 72M)
//SPI_BaudRatePrescaler_32 32分频 (SPI 2.25M@sys 72M)
//SPI_BaudRatePrescaler_256 256分频 (SPI 281.25K@sys 72M)
//SPI1 速度设置函数
void SPI1_SetSpeed(u8 SpeedSet)
{
assert_param(IS_SPI_BAUDRATE_PRESCALER(SpeedSet));
SPI1->CR1&=0XFFC7;
SPI1->CR1|=SpeedSet; //设置SPI1速度
SPI_Cmd(SPI1,ENABLE);
}
//SPI1 读写一个字节
//TxData 要写入的字节
//返回值 读取到的字节
u8 SPI1_ReadWriteByte(u8 TxData)
{
u8 retry=0;
while((SPI1->SR&1<<1)==0)//检查指定的标志位设置与否;发送缓存空标志位
{
retry++;
if(retry>200)return 0;
}
SPI1->DR=TxData; //通过外设SPIx发送一个byte
retry=0;
while((SPI1->SR&1<<0)==0) //检查指定的标志位设置与否;接收缓存非空标志位
{
retry++;
if(retry>200)return 0;
}
return SPI1->DR; //返回通过外设SPIx最近接收的数据
}
void SPI2_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE );//PORTB时钟使能
RCC_APB1PeriphClockCmd( RCC_APB1Periph_SPI2, ENABLE );//SPI2时钟使能
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //PB13/14/15复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //双线双向全双工
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //设置为主SPI
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //SPI发送8bit数据
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //第二个时钟沿数据被采样
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //片选由软件控制
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2; // 时钟分频72M/x
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //高位在前
SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC计算值的多项式
SPI_Init(SPI2,&SPI_InitStructure);
SPI_Cmd(SPI2, ENABLE); //使能SPI外设
}
//SPI 速度设置函数
//SpeedSet:
//SPI_BaudRatePrescaler_2 2分频
//SPI_BaudRatePrescaler_8 8分频
//SPI_BaudRatePrescaler_16 16分频
//SPI_BaudRatePrescaler_256 256分频
void SPI2_SetSpeed(u8 SPI_BaudRatePrescaler)
{
assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));
SPI2->CR1&=0XFFC7;
SPI2->CR1|=SPI_BaudRatePrescaler; //设置SPI2速度
SPI_Cmd(SPI2,ENABLE);
}
//SPIx 读写一个字节
//TxData:要写入的字节
//返回值:读取到的字节
u8 SPI2_ReadWriteByte(u8 TxData)
{
u8 retry=0;
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位
{
retry++;
if(retry>200)return 0;
}
SPI_I2S_SendData(SPI2, TxData); //通过外设SPIx发送一个数据
retry=0;
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET) //检查指定的SPI标志位设置与否:接受缓存非空标志位
{
retry++;
if(retry>200)return 0;
}
return SPI_I2S_ReceiveData(SPI2); //返回通过SPIx最近接收的数据
}
#ifndef __SPI_H
#define __SPI_H
#include "sys.h"
u8 SPI1_ReadWriteByte(u8 TxData);//SPI总线读写一个字节
u8 SPI2_ReadWriteByte(u8 TxData);//SPI总线读写一个字节
u8 SPI3_ReadWriteByte(u8 TxData);//SPI总线读写一个字节
void SPI1_SetSpeed(u8 SpeedSet); //设置SPI速度
void SPI2_SetSpeed(u8 SpeedSet); //设置SPI速度
void SPI3_SetSpeed(u8 SpeedSet); //设置SPI速度
void SPI1_Init(void); //初始化SPI口
void SPI2_Init(void); //初始化SPI口
void SPI3_Init(void); //初始化SPI口
#endif
#ifndef __USART_H
#define __USART_H
#include "sys.h"
#include "myQueue.h"
#define UART_REC_LENGTH 256 //接收缓冲区
#define UART_SEND_LENGTH 256 //发送缓冲区
#define UART1_DEBUG 1
#define USART_REC_LEN 255 ////串口接收缓冲区大小
//////////////////////////////////////////////////////////////////////////
#if UART1_DEBUG == 1
#define Main_printf(...) printf(__VA_ARGS__)
#else
#define Main_printf(...)
#endif
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
#define UART_QUEUE_LENGTH 27 //(队列容量)缓冲区有效数据长度24*38=912
#define UART_QUEUE_SIZE 150 //队列大小
__align(4) typedef struct {
u16 sendlength;
u16 reclength;
u8 *sendbuf; //发送缓冲区
u8 *recbuf; //接收缓冲区
QueueInfo *USART_Queue;
}_UART_Info;
extern _UART_Info *UART_Info ; //上传数据结构
//////////////////////////////////////////////////////////////////////////
extern u8 USART_RX_BUF[USART_REC_LEN] ; //接收缓冲
extern u16 USART_RX_STA; //接收状态标记
extern u8 USART1_RX_BUF[USART_REC_LEN] ; //接收缓冲
extern u16 USART1_RX_LEN;
extern u16 USART1_TIME;
extern u8 USART2_RX_BUF[USART_REC_LEN] ; //接收缓冲
extern u16 USART2_RX_LEN;
extern u16 USART2_TIME;
extern u8 USART3_RX_BUF[USART_REC_LEN] ; //接收缓冲
extern u16 USART3_RX_LEN;
extern u16 USART3_TIME;
//////////////////////////////////////////////////////////////////////////
void uart1_init(u32 bound);
void uart2_init(u32 bound);
void uart3_init(u32 bound);
void uart4_init(u32 bound);
//void u2_printf(char* fmt,...);
//void u3_printf(char* fmt,...);
//void u4_printf(char* fmt,...);
void USART2_Clear(void);
void USART3_Clear(void);
//////////////////////////////////////////////////////////////////////////////
void USARTx_Send(USART_TypeDef* USARTx, u8 *Data, u16 Len);
void UART1_Send_STR(u8* cmd);
void UART2_Send_STR(u8* cmd);
void UART3_Send_STR(u8* cmd);
s16 Str_search(u8* buf,u8 len,u8* result);//判断指定字符串是否在数组中
s16 char_search(u8* buf,u8 len,u8 result);
#endif
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************
LR_IROM1 0x08000000 0x00010000 { ; load region size_region
ER_IROM1 0x08000000 0x00010000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_IRAM1 0x20000000 0x00005000 { ; RW data
.ANY (+RW +ZI)
}
}
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************
LR_IROM1 0x08000000 0x00010000 { ; load region size_region
ER_IROM1 0x08000000 0x00010000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
.ANY (+XO)
}
RW_IRAM1 0x20000000 0x00005000 { ; RW data
.ANY (+RW +ZI)
}
}
File added
File added
File added
File added
File added
File added
File added
File added
File added
/**
******************************************************************************
* @file misc.h
* @author MCD Application Team
* @version V3.5.0
* @date 11-March-2011
* @brief This file contains all the functions prototypes for the miscellaneous
* firmware library functions (add-on to CMSIS functions).
******************************************************************************
* @attention
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MISC_H
#define __MISC_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
/** @addtogroup STM32F10x_StdPeriph_Driver
* @{
*/
/** @addtogroup MISC
* @{
*/
/** @defgroup MISC_Exported_Types
* @{
*/
/**
* @brief NVIC Init Structure definition
*/
typedef struct
{
uint8_t NVIC_IRQChannel; /*!< Specifies the IRQ channel to be enabled or disabled.
This parameter can be a value of @ref IRQn_Type
(For the complete STM32 Devices IRQ Channels list, please
refer to stm32f10x.h file) */
uint8_t NVIC_IRQChannelPreemptionPriority; /*!< Specifies the pre-emption priority for the IRQ channel
specified in NVIC_IRQChannel. This parameter can be a value
between 0 and 15 as described in the table @ref NVIC_Priority_Table */
uint8_t NVIC_IRQChannelSubPriority; /*!< Specifies the subpriority level for the IRQ channel specified
in NVIC_IRQChannel. This parameter can be a value
between 0 and 15 as described in the table @ref NVIC_Priority_Table */
FunctionalState NVIC_IRQChannelCmd; /*!< Specifies whether the IRQ channel defined in NVIC_IRQChannel
will be enabled or disabled.
This parameter can be set either to ENABLE or DISABLE */
} NVIC_InitTypeDef;
/**
* @}
*/
/** @defgroup NVIC_Priority_Table
* @{
*/
/**
@code
The table below gives the allowed values of the pre-emption priority and subpriority according
to the Priority Grouping configuration performed by NVIC_PriorityGroupConfig function
============================================================================================================================
NVIC_PriorityGroup | NVIC_IRQChannelPreemptionPriority | NVIC_IRQChannelSubPriority | Description
============================================================================================================================
NVIC_PriorityGroup_0 | 0 | 0-15 | 0 bits for pre-emption priority
| | | 4 bits for subpriority
----------------------------------------------------------------------------------------------------------------------------
NVIC_PriorityGroup_1 | 0-1 | 0-7 | 1 bits for pre-emption priority
| | | 3 bits for subpriority
----------------------------------------------------------------------------------------------------------------------------
NVIC_PriorityGroup_2 | 0-3 | 0-3 | 2 bits for pre-emption priority
| | | 2 bits for subpriority
----------------------------------------------------------------------------------------------------------------------------
NVIC_PriorityGroup_3 | 0-7 | 0-1 | 3 bits for pre-emption priority
| | | 1 bits for subpriority
----------------------------------------------------------------------------------------------------------------------------
NVIC_PriorityGroup_4 | 0-15 | 0 | 4 bits for pre-emption priority
| | | 0 bits for subpriority
============================================================================================================================
@endcode
*/
/**
* @}
*/
/** @defgroup MISC_Exported_Constants
* @{
*/
/** @defgroup Vector_Table_Base
* @{
*/
#define NVIC_VectTab_RAM ((uint32_t)0x20000000)
#define NVIC_VectTab_FLASH ((uint32_t)0x08000000)
#define IS_NVIC_VECTTAB(VECTTAB) (((VECTTAB) == NVIC_VectTab_RAM) || \
((VECTTAB) == NVIC_VectTab_FLASH))
/**
* @}
*/
/** @defgroup System_Low_Power
* @{
*/
#define NVIC_LP_SEVONPEND ((uint8_t)0x10)
#define NVIC_LP_SLEEPDEEP ((uint8_t)0x04)
#define NVIC_LP_SLEEPONEXIT ((uint8_t)0x02)
#define IS_NVIC_LP(LP) (((LP) == NVIC_LP_SEVONPEND) || \
((LP) == NVIC_LP_SLEEPDEEP) || \
((LP) == NVIC_LP_SLEEPONEXIT))
/**
* @}
*/
/** @defgroup Preemption_Priority_Group
* @{
*/
#define NVIC_PriorityGroup_0 ((uint32_t)0x700) /*!< 0 bits for pre-emption priority
4 bits for subpriority */
#define NVIC_PriorityGroup_1 ((uint32_t)0x600) /*!< 1 bits for pre-emption priority
3 bits for subpriority */
#define NVIC_PriorityGroup_2 ((uint32_t)0x500) /*!< 2 bits for pre-emption priority
2 bits for subpriority */
#define NVIC_PriorityGroup_3 ((uint32_t)0x400) /*!< 3 bits for pre-emption priority
1 bits for subpriority */
#define NVIC_PriorityGroup_4 ((uint32_t)0x300) /*!< 4 bits for pre-emption priority
0 bits for subpriority */
#define IS_NVIC_PRIORITY_GROUP(GROUP) (((GROUP) == NVIC_PriorityGroup_0) || \
((GROUP) == NVIC_PriorityGroup_1) || \
((GROUP) == NVIC_PriorityGroup_2) || \
((GROUP) == NVIC_PriorityGroup_3) || \
((GROUP) == NVIC_PriorityGroup_4))
#define IS_NVIC_PREEMPTION_PRIORITY(PRIORITY) ((PRIORITY) < 0x10)
#define IS_NVIC_SUB_PRIORITY(PRIORITY) ((PRIORITY) < 0x10)
#define IS_NVIC_OFFSET(OFFSET) ((OFFSET) < 0x000FFFFF)
/**
* @}
*/
/** @defgroup SysTick_clock_source
* @{
*/
#define SysTick_CLKSource_HCLK_Div8 ((uint32_t)0xFFFFFFFB)
#define SysTick_CLKSource_HCLK ((uint32_t)0x00000004)
#define IS_SYSTICK_CLK_SOURCE(SOURCE) (((SOURCE) == SysTick_CLKSource_HCLK) || \
((SOURCE) == SysTick_CLKSource_HCLK_Div8))
/**
* @}
*/
/**
* @}
*/
/** @defgroup MISC_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup MISC_Exported_Functions
* @{
*/
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);
void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset);
void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState);
void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource);
#ifdef __cplusplus
}
#endif
#endif /* __MISC_H */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
/**
******************************************************************************
* @file stm32f10x_bkp.h
* @author MCD Application Team
* @version V3.5.0
* @date 11-March-2011
* @brief This file contains all the functions prototypes for the BKP firmware
* library.
******************************************************************************
* @attention
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32F10x_BKP_H
#define __STM32F10x_BKP_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
/** @addtogroup STM32F10x_StdPeriph_Driver
* @{
*/
/** @addtogroup BKP
* @{
*/
/** @defgroup BKP_Exported_Types
* @{
*/
/**
* @}
*/
/** @defgroup BKP_Exported_Constants
* @{
*/
/** @defgroup Tamper_Pin_active_level
* @{
*/
#define BKP_TamperPinLevel_High ((uint16_t)0x0000)
#define BKP_TamperPinLevel_Low ((uint16_t)0x0001)
#define IS_BKP_TAMPER_PIN_LEVEL(LEVEL) (((LEVEL) == BKP_TamperPinLevel_High) || \
((LEVEL) == BKP_TamperPinLevel_Low))
/**
* @}
*/
/** @defgroup RTC_output_source_to_output_on_the_Tamper_pin
* @{
*/
#define BKP_RTCOutputSource_None ((uint16_t)0x0000)
#define BKP_RTCOutputSource_CalibClock ((uint16_t)0x0080)
#define BKP_RTCOutputSource_Alarm ((uint16_t)0x0100)
#define BKP_RTCOutputSource_Second ((uint16_t)0x0300)
#define IS_BKP_RTC_OUTPUT_SOURCE(SOURCE) (((SOURCE) == BKP_RTCOutputSource_None) || \
((SOURCE) == BKP_RTCOutputSource_CalibClock) || \
((SOURCE) == BKP_RTCOutputSource_Alarm) || \
((SOURCE) == BKP_RTCOutputSource_Second))
/**
* @}
*/
/** @defgroup Data_Backup_Register
* @{
*/
#define BKP_DR1 ((uint16_t)0x0004)
#define BKP_DR2 ((uint16_t)0x0008)
#define BKP_DR3 ((uint16_t)0x000C)
#define BKP_DR4 ((uint16_t)0x0010)
#define BKP_DR5 ((uint16_t)0x0014)
#define BKP_DR6 ((uint16_t)0x0018)
#define BKP_DR7 ((uint16_t)0x001C)
#define BKP_DR8 ((uint16_t)0x0020)
#define BKP_DR9 ((uint16_t)0x0024)
#define BKP_DR10 ((uint16_t)0x0028)
#define BKP_DR11 ((uint16_t)0x0040)
#define BKP_DR12 ((uint16_t)0x0044)
#define BKP_DR13 ((uint16_t)0x0048)
#define BKP_DR14 ((uint16_t)0x004C)
#define BKP_DR15 ((uint16_t)0x0050)
#define BKP_DR16 ((uint16_t)0x0054)
#define BKP_DR17 ((uint16_t)0x0058)
#define BKP_DR18 ((uint16_t)0x005C)
#define BKP_DR19 ((uint16_t)0x0060)
#define BKP_DR20 ((uint16_t)0x0064)
#define BKP_DR21 ((uint16_t)0x0068)
#define BKP_DR22 ((uint16_t)0x006C)
#define BKP_DR23 ((uint16_t)0x0070)
#define BKP_DR24 ((uint16_t)0x0074)
#define BKP_DR25 ((uint16_t)0x0078)
#define BKP_DR26 ((uint16_t)0x007C)
#define BKP_DR27 ((uint16_t)0x0080)
#define BKP_DR28 ((uint16_t)0x0084)
#define BKP_DR29 ((uint16_t)0x0088)
#define BKP_DR30 ((uint16_t)0x008C)
#define BKP_DR31 ((uint16_t)0x0090)
#define BKP_DR32 ((uint16_t)0x0094)
#define BKP_DR33 ((uint16_t)0x0098)
#define BKP_DR34 ((uint16_t)0x009C)
#define BKP_DR35 ((uint16_t)0x00A0)
#define BKP_DR36 ((uint16_t)0x00A4)
#define BKP_DR37 ((uint16_t)0x00A8)
#define BKP_DR38 ((uint16_t)0x00AC)
#define BKP_DR39 ((uint16_t)0x00B0)
#define BKP_DR40 ((uint16_t)0x00B4)
#define BKP_DR41 ((uint16_t)0x00B8)
#define BKP_DR42 ((uint16_t)0x00BC)
#define IS_BKP_DR(DR) (((DR) == BKP_DR1) || ((DR) == BKP_DR2) || ((DR) == BKP_DR3) || \
((DR) == BKP_DR4) || ((DR) == BKP_DR5) || ((DR) == BKP_DR6) || \
((DR) == BKP_DR7) || ((DR) == BKP_DR8) || ((DR) == BKP_DR9) || \
((DR) == BKP_DR10) || ((DR) == BKP_DR11) || ((DR) == BKP_DR12) || \
((DR) == BKP_DR13) || ((DR) == BKP_DR14) || ((DR) == BKP_DR15) || \
((DR) == BKP_DR16) || ((DR) == BKP_DR17) || ((DR) == BKP_DR18) || \
((DR) == BKP_DR19) || ((DR) == BKP_DR20) || ((DR) == BKP_DR21) || \
((DR) == BKP_DR22) || ((DR) == BKP_DR23) || ((DR) == BKP_DR24) || \
((DR) == BKP_DR25) || ((DR) == BKP_DR26) || ((DR) == BKP_DR27) || \
((DR) == BKP_DR28) || ((DR) == BKP_DR29) || ((DR) == BKP_DR30) || \
((DR) == BKP_DR31) || ((DR) == BKP_DR32) || ((DR) == BKP_DR33) || \
((DR) == BKP_DR34) || ((DR) == BKP_DR35) || ((DR) == BKP_DR36) || \
((DR) == BKP_DR37) || ((DR) == BKP_DR38) || ((DR) == BKP_DR39) || \
((DR) == BKP_DR40) || ((DR) == BKP_DR41) || ((DR) == BKP_DR42))
#define IS_BKP_CALIBRATION_VALUE(VALUE) ((VALUE) <= 0x7F)
/**
* @}
*/
/**
* @}
*/
/** @defgroup BKP_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup BKP_Exported_Functions
* @{
*/
void BKP_DeInit(void);
void BKP_TamperPinLevelConfig(uint16_t BKP_TamperPinLevel);
void BKP_TamperPinCmd(FunctionalState NewState);
void BKP_ITConfig(FunctionalState NewState);
void BKP_RTCOutputConfig(uint16_t BKP_RTCOutputSource);
void BKP_SetRTCCalibrationValue(uint8_t CalibrationValue);
void BKP_WriteBackupRegister(uint16_t BKP_DR, uint16_t Data);
uint16_t BKP_ReadBackupRegister(uint16_t BKP_DR);
FlagStatus BKP_GetFlagStatus(void);
void BKP_ClearFlag(void);
ITStatus BKP_GetITStatus(void);
void BKP_ClearITPendingBit(void);
#ifdef __cplusplus
}
#endif
#endif /* __STM32F10x_BKP_H */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
/**
******************************************************************************
* @file stm32f10x_cec.h
* @author MCD Application Team
* @version V3.5.0
* @date 11-March-2011
* @brief This file contains all the functions prototypes for the CEC firmware
* library.
******************************************************************************
* @attention
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32F10x_CEC_H
#define __STM32F10x_CEC_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
/** @addtogroup STM32F10x_StdPeriph_Driver
* @{
*/
/** @addtogroup CEC
* @{
*/
/** @defgroup CEC_Exported_Types
* @{
*/
/**
* @brief CEC Init structure definition
*/
typedef struct
{
uint16_t CEC_BitTimingMode; /*!< Configures the CEC Bit Timing Error Mode.
This parameter can be a value of @ref CEC_BitTiming_Mode */
uint16_t CEC_BitPeriodMode; /*!< Configures the CEC Bit Period Error Mode.
This parameter can be a value of @ref CEC_BitPeriod_Mode */
}CEC_InitTypeDef;
/**
* @}
*/
/** @defgroup CEC_Exported_Constants
* @{
*/
/** @defgroup CEC_BitTiming_Mode
* @{
*/
#define CEC_BitTimingStdMode ((uint16_t)0x00) /*!< Bit timing error Standard Mode */
#define CEC_BitTimingErrFreeMode CEC_CFGR_BTEM /*!< Bit timing error Free Mode */
#define IS_CEC_BIT_TIMING_ERROR_MODE(MODE) (((MODE) == CEC_BitTimingStdMode) || \
((MODE) == CEC_BitTimingErrFreeMode))
/**
* @}
*/
/** @defgroup CEC_BitPeriod_Mode
* @{
*/
#define CEC_BitPeriodStdMode ((uint16_t)0x00) /*!< Bit period error Standard Mode */
#define CEC_BitPeriodFlexibleMode CEC_CFGR_BPEM /*!< Bit period error Flexible Mode */
#define IS_CEC_BIT_PERIOD_ERROR_MODE(MODE) (((MODE) == CEC_BitPeriodStdMode) || \
((MODE) == CEC_BitPeriodFlexibleMode))
/**
* @}
*/
/** @defgroup CEC_interrupts_definition
* @{
*/
#define CEC_IT_TERR CEC_CSR_TERR
#define CEC_IT_TBTRF CEC_CSR_TBTRF
#define CEC_IT_RERR CEC_CSR_RERR
#define CEC_IT_RBTF CEC_CSR_RBTF
#define IS_CEC_GET_IT(IT) (((IT) == CEC_IT_TERR) || ((IT) == CEC_IT_TBTRF) || \
((IT) == CEC_IT_RERR) || ((IT) == CEC_IT_RBTF))
/**
* @}
*/
/** @defgroup CEC_Own_Address
* @{
*/
#define IS_CEC_ADDRESS(ADDRESS) ((ADDRESS) < 0x10)
/**
* @}
*/
/** @defgroup CEC_Prescaler
* @{
*/
#define IS_CEC_PRESCALER(PRESCALER) ((PRESCALER) <= 0x3FFF)
/**
* @}
*/
/** @defgroup CEC_flags_definition
* @{
*/
/**
* @brief ESR register flags
*/
#define CEC_FLAG_BTE ((uint32_t)0x10010000)
#define CEC_FLAG_BPE ((uint32_t)0x10020000)
#define CEC_FLAG_RBTFE ((uint32_t)0x10040000)
#define CEC_FLAG_SBE ((uint32_t)0x10080000)
#define CEC_FLAG_ACKE ((uint32_t)0x10100000)
#define CEC_FLAG_LINE ((uint32_t)0x10200000)
#define CEC_FLAG_TBTFE ((uint32_t)0x10400000)
/**
* @brief CSR register flags
*/
#define CEC_FLAG_TEOM ((uint32_t)0x00000002)
#define CEC_FLAG_TERR ((uint32_t)0x00000004)
#define CEC_FLAG_TBTRF ((uint32_t)0x00000008)
#define CEC_FLAG_RSOM ((uint32_t)0x00000010)
#define CEC_FLAG_REOM ((uint32_t)0x00000020)
#define CEC_FLAG_RERR ((uint32_t)0x00000040)
#define CEC_FLAG_RBTF ((uint32_t)0x00000080)
#define IS_CEC_CLEAR_FLAG(FLAG) ((((FLAG) & (uint32_t)0xFFFFFF03) == 0x00) && ((FLAG) != 0x00))
#define IS_CEC_GET_FLAG(FLAG) (((FLAG) == CEC_FLAG_BTE) || ((FLAG) == CEC_FLAG_BPE) || \
((FLAG) == CEC_FLAG_RBTFE) || ((FLAG)== CEC_FLAG_SBE) || \
((FLAG) == CEC_FLAG_ACKE) || ((FLAG) == CEC_FLAG_LINE) || \
((FLAG) == CEC_FLAG_TBTFE) || ((FLAG) == CEC_FLAG_TEOM) || \
((FLAG) == CEC_FLAG_TERR) || ((FLAG) == CEC_FLAG_TBTRF) || \
((FLAG) == CEC_FLAG_RSOM) || ((FLAG) == CEC_FLAG_REOM) || \
((FLAG) == CEC_FLAG_RERR) || ((FLAG) == CEC_FLAG_RBTF))
/**
* @}
*/
/**
* @}
*/
/** @defgroup CEC_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup CEC_Exported_Functions
* @{
*/
void CEC_DeInit(void);
void CEC_Init(CEC_InitTypeDef* CEC_InitStruct);
void CEC_Cmd(FunctionalState NewState);
void CEC_ITConfig(FunctionalState NewState);
void CEC_OwnAddressConfig(uint8_t CEC_OwnAddress);
void CEC_SetPrescaler(uint16_t CEC_Prescaler);
void CEC_SendDataByte(uint8_t Data);
uint8_t CEC_ReceiveDataByte(void);
void CEC_StartOfMessage(void);
void CEC_EndOfMessageCmd(FunctionalState NewState);
FlagStatus CEC_GetFlagStatus(uint32_t CEC_FLAG);
void CEC_ClearFlag(uint32_t CEC_FLAG);
ITStatus CEC_GetITStatus(uint8_t CEC_IT);
void CEC_ClearITPendingBit(uint16_t CEC_IT);
#ifdef __cplusplus
}
#endif
#endif /* __STM32F10x_CEC_H */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment