自制的AVR离线下载器,使用的STM32F103C8T6单片机,通过上位机,发送hex文件,然后存在SD卡中,下位机带有文件系统,也可以通过电脑,按一定的格式,直接复制在SD当中。
上位机界面:
上位机源码:
stm32单片机下位机源程序如下:
- /*******************************************************************
- *
- * 模块名称 : 程序脚本
- * 文件名称 : main.c
- * 版 本 : V1.0
- * 说 明 : 硬件底层驱动程序集合
- * 芯 片 : STM32F103C8T6(48个外围引脚,64K Flash,LQFP封装,20K SRAM)
- *----------------修改记录------------------
- * 版 本 号 :
- * 修改日期 :
- * 作 者 : ChenLin
- * 说 明 :
- *
- ********************************************************************/
- #include "main.h"
- #include "spi.h"
- #include "AVR_Download.h"
- #include "sd.h"
- #include "HMI_Display.h"
- #define BOARD_TEST //打开板子测试
- #define BEEP PAout(9)
- /* 文件系统相关定义 ---------------------------------------------------------*/
- ///////////////////////////////////////////////////
- #define READ_TEST
- FATFS fs;// Work area (file system object) for logical drive
- FRESULT res;// FatFs function common result code
- FIL fsrc, fdst; // file objects
- BYTE buffer[512]; // file copy buffer
- UINT br, bw; // File R/W count
- DIR Folder;
- unsigned char w_buffer[]={"test\r\n"};//演示写入文件
- const char folder_name[] = {"/system"}; //文件夹名字
- char file_path[FILE_LONG];//文件路径
- char newfile_path[FILE_LONG];//新文件路径,改文件名用
- #ifdef READ_TEST
- unsigned char r_buffer[512];//演示读入文件
- #endif
- ////////////////////////////////////////////////////
- int T1,T2,T3;
- /***************************************************************************
- ;** 函数名称: void RCC_Configuration(void)
- ;** 功能描述: RCC时针配置
- ;** 输入参数:
- ;** 返 回 值:
- ;** 全局变量:
- ;** 调用模块:
- ;** 作 者: ChenLin
- ;** 日 期: 2017-1-13
- ;** 修改原因:
- ;** 说 明:
- ;***************************************************************************/
- void RCC_Configuration(void)
- {
- RCC_DeInit(); //初始化为缺省值
- RCC_HSEConfig(RCC_HSE_ON); //使能外部的高速时钟
- while(RCC_GetFlagStatus(RCC_FLAG_HSERDY)==RESET); //等待外部高速时钟就绪
- FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);//Enable Prefetch Buffer
- FLASH_SetLatency(FLASH_Latency_2); //Flash 2 wait state
- RCC_HCLKConfig(RCC_SYSCLK_Div1);
- RCC_PCLK2Config(RCC_HCLK_Div1); //PCLK2=HCLK
- RCC_PCLK1Config(RCC_HCLK_Div2); //PCLK2=HCLK/2
- RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); //PLLCLK=8MHZ*9=72MH
- RCC_PLLCmd(ENABLE); //ENABLE PLLCLK
- while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET); //Wait till PLLCLK is ready
- RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //Set PLL as system clock
- while(RCC_GetSYSCLKSource() != 0x08); //等待直到PLLCLK为系统时钟
- RCC->CR |= (uint32_t)0x00080000; //打开CSS(时钟监视系统)
- //***********打开相应的外设************//
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
- //SystemInit(); //全部外部时钟; 固件库默认
- }
- /***************************************************************************
- ;** 函数名称: void testProgram()
- ;** 功能描述: 用来测试板子的好坏,一输入对应一输出
- ;** 输入参数:
- ;** 返 回 值:
- ;** 全局变量:
- ;** 调用模块:
- ;** 作 者: ChenLin
- ;** 日 期: 2017-1-13
- ;** 修改原因:
- ;** 说 明:
- ;***************************************************************************/
- void testProgram()
- {
- if(!S1)
- OUT1 = ON;
- else
- OUT1 = OFF;
- if(!S2)
- OUT2 = ON;
- else
- OUT2 = OFF;
- if(!S3)
- OUT3 = ON;
- else
- OUT3 = OFF;
- if(!S4)
- OUT4 = ON;
- else
- OUT4 = OFF;
- if(!S5)
- OUT5 = ON;
- else
- OUT5 = OFF;
- if(!S6)
- OUT6 = ON;
- else
- OUT6 = OFF;
- if(!S7)
- OUT7 = ON;
- else
- OUT7 = OFF;
- if(!S8)
- OUT8 = ON;
- else
- OUT8 = OFF;
- if(!S9)
- OUT9 = ON;
- else
- OUT9 = OFF;
- if(!S10)
- OUT10 = ON;
- else
- OUT10 = OFF;
- if(!S11)
- OUT11 = ON;
- else
- OUT11 = OFF;
- if(!S12)
- OUT12 = ON;
- else
- OUT12 = OFF;
- if(!S13)
- OUT13 = ON;
- else
- OUT13 = OFF;
- if(!S14)
- OUT14 = ON;
- else
- OUT14 = OFF;
- if(!S15)
- OUT15 = ON;
- else
- OUT15 = OFF;
- if(!S16)
- OUT16 = ON;
- else
- OUT16 = OFF;
-
- }
- /***************************************************************************
- ;** 函数名称: void Get_File_Path(char *pp)
- ;** 输入参数: 得到文件路么,把文件名和文件夹名合成一个路径
- ;** 返 回 值:
- ;** 全局变量:
- ;** 调用模块:
- ;** 作 者: ChenLin
- ;** 日 期: 2017-7-26
- ;** 修改原因:
- ;** 说 明:
- ;***************************************************************************/
- void Get_File_Path(char *path,char *pp)
- {
- u8 i = 0;
- char file_att[] = ".txt";//文件属性
- //清空数组
- for(i = 0;path[i] != 0;i++)
- {
- path[i] = 0;
- }
-
- //加入文件夹名字
- for(i = 0;folder_name[i] != 0;i++)
- {
- *path++ = folder_name[i];
- }
- *path++ = '/';
-
- //加入文件名字
- while((*pp != '\r') && (*pp != '\n') && (*pp != '\0'))
- {
- *path++ = *pp++;
- }
- //加入文件属性
- for(i = 0;file_att[i] != 0;i++)
- {
- *path++ = file_att[i];
- }
- *path = 0;
- }
- /***************************************************************************
- ;** 函数名称: void FATFS_Init(void)
- ;** 输入参数: FATFS文件系统相关初始化
- ;** 返 回 值:
- ;** 全局变量:
- ;** 调用模块:
- ;** 作 者: ChenLin
- ;** 日 期: 2017-7-22
- ;** 修改原因:
- ;** 说 明:
- ;***************************************************************************/
- void FATFS_Init()
- {
- DIR Folder;
- char file_name[] = "test1";
- FIL *file = &fsrc;
- u32 offset = 0;
- disk_initialize(0);
- res = f_mount(&fs,"0:",1);
- res = f_mkdir(folder_name);//创建一个文件夹
- res = f_opendir(&Folder,folder_name);
- Get_File_Path(file_path,file_name); //得到文件路径
-
- res=f_open(&fsrc,file_path,FA_CREATE_ALWAYS | FA_WRITE |FA_READ);
- if(res == FR_OK)
- {
- printfU3("打开文件成功\r\n");
- }
- else if(res == FR_NO_FILE)
- {
- printfU3("找不到该文件\r\n");
- }
- else if(res == FR_NO_PATH)
- {
- printfU3("找不到该路径\r\n");
- }
- else if(res == FR_INVALID_NAME)
- {
- printfU3("文件名无效\r\n");
- }
- else if(res == FR_INVALID_DRIVE)
- {
- printfU3("驱动器号无效\r\n");
- }
- else if(res == FR_NOT_READY )
- {
- printfU3("驱动器中没有存储介质\r\n");
- }
- else if(res == FR_NO_FILESYSTEM )
- {
- printfU3("磁盘上没有有效地FAT卷。\r\n");
- }
-
- res = f_write(file, &w_buffer, strlen((char*)w_buffer), &bw);
- offset+=bw;
- f_lseek(file,offset);
- res = f_write(file, "chenlin\r\n", 10, &bw);
- if(res == FR_OK )
- {
- printfU3("写入成功!\r\n");
- }
- else
- {
- printfU3("写入失败!\r\n");
- }
-
- res=f_close(&fsrc);
-
- if(res == FR_OK )
- {
- printfU3("关闭成功!\r\n");
- }
- else
- {
- printfU3("关闭失败!\r\n");
- }
-
- #ifdef READ_TEST
- // f_unlink(file_path);//删除文件
- res = f_opendir(&Folder,folder_name);
- res=f_open(&fsrc,file_path,FA_READ);
- f_gets((char*)r_buffer,32,&fsrc);
- sprintfU3("r=%s\r\n",r_buffer);
- offset = strlen((char*)r_buffer);
- f_gets((char*)r_buffer,32,&fsrc);
- sprintfU3("r=%s\r\n",r_buffer);
- res=f_close(&fsrc);
- #endif
-
- }
- /***************************************************************************
- ;** 函数名称: void buttonFunction()
- ;** 功能描述: 三个独立按钮功能程序,按钮实现上下翻页
- ;** 输入参数:
- ;** 返 回 值:
- ;** 全局变量:
- ;** 调用模块:
- ;** 作 者: ChenLin
- ;** 日 期: 2017-7-27
- ;** 修改原因:
- ;** 说 明:
- ;***************************************************************************/
- void buttonFunction()
- {
-
- if(S5 && S9)
- p->flag[2] = false;
- if(p->flag[2] == false)
- if(!S5 && !S9) //同时按下S5和S9开关蜂鸣器
- {
- p->flag[2] = true;
- p->LockBeep = ~(p->LockBeep);
- if(p->LockBeep == true)
- {
- HMISends("t9.txt=\"蜂鸣器失效\"");
- HMISendb(0xff,3);
- HMISends("t9.bco=65504");//控件颜色为黄色
- HMISendb(0xff,3);
- HMISends("vis t9,1");
- HMISendb(0xff,3);
- delay_Nms(1000);
- HMISends("vis t9,0");
- HMISendb(0xff,3);
- }
- else
- {
- HMISends("t9.txt=\"蜂鸣器已打开\"");
- HMISendb(0xff,3);
- HMISends("t9.bco=2024");//控件颜色为亮绿色
- HMISendb(0xff,3);
- HMISends("vis t9,1");
- HMISendb(0xff,3);
- delay_Nms(1000);
- HMISends("vis t9,0");
- HMISendb(0xff,3);
- }
- return;
- }
-
- if(p->flag[1] == false)
- if(p->LastPage) //上一页
- {
- p->flag[1] = true;
- Read_Num = Read_Num - 1;
- if(Read_Num <= 0)
- {
- Read_Num = 100;
- }
- AVR.flag1 = true; //加标志
- AVR.flashUpdate = false; //刷新flash标志
- return;
- }
-
- if(p->NextPage) //下一页
- {
- while(!S5)
- {
- keyScan();
- if(p->ProgramStatus == true) //是长按
- {
- return;
- }
- }
- Read_Num = Read_Num + 1;
- if(Read_Num > 100)
- {
- Read_Num = 1;
- }
- AVR.flag1 = false;
- AVR.flashUpdate = false; //刷新flash标志,fasle有效
- }
-
- }
- void BeepControl(u8 n)
- {
- if((p->LockBeep == false)&&(n == ON))
- {
- BEEP = ON;
- delay_Nms(400);
- BEEP = OFF;
- }
- else
- BEEP = OFF;
- }
- int main()
- {
- RXstructure *p3 = &usart3_buf;
- RXstructure *p2 = &usart2_buf;
- uint32_t sdCapacity;
- u8 i = 0;
- delay_Nms(500); //上电延时
- RCC_Configuration();
- GPIO_Configuration();
- IIC_Configuration();
- TIM3_Configuration(35999, 10, 5); //定时5ms
- TIM4_Configuration(35999, 10, 5); //定时5ms
- USART3_Configuration(115200);
- USART2_Configuration(9600);
- SPI1_Config(); //与AVR通信
- SPI2_Config(); //SD卡通信
-
- printfU3("communication finish\r\n");
- while(SD_Init()) //SD卡初始化
- {
- i++;
- if(i>10)
- {
- HMISends("page no SD Card");
- HMISendb(0xff,3);
- while(SD_Init()); //SD卡初始化
- }
- }
-
- printfU3("SD卡初始化成功\r\n");
- SD_ReadCapacity(&sdCapacity);
- sprintfU3("SD卡扇区数:%d ",sdCapacity);
- if(SD_TYPE == SD_TYPE_V2HC)
- printfU3("This is High Capacity SD Memory Card\r\n");
- else if(SD_TYPE == SD_TYPE_V2)
- printfU3("This is Standard Capacity SD Memory Card\r\n");
-
- HMI_Init();
-
- FATFS_Init(); //FATFS文件系统初始化
- while(1)
- {
- keyScan();
- buttonFunction();//按键功能
- if(p->ProgramStatus)
- {
- AVR.programFlag = ~AVR.programFlag;
-
- if(AVR.programFlag==true)
- {
- printfU3("enter program status\r\n");
- HMISends("page program");
- HMISendb(0xff,3);
-
- }
- else
- {
- printfU3("quit program status\r\n");
- HMISends("page main");
- HMISendb(0xff,3);
- Read_Num=IIC_Read_Data(num_Addr); //读保存的镜像号
- AVR.flashUpdate = false;
- }
- AVR.flag2 = false; //如果没找到flash,再进入一次HMI显示no flash操作
- BeepControl(ON);
- while(!S5);
- delay_Nms(10);
- }
-
- //编程状态
- if(AVR.programFlag == true)
- {
-
- if(p3->flagRec)
- {
- if(p3->data[0] == ':') //接收到的是hex文件
- Save_Data_To_Flash();
- else //接收到的是命令
- {
- usart3Function();
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
AVR离线下载器-上位机.zip
(100.88 KB, 下载次数: 186)
|