找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 13944|回复: 22
收起左侧

自制AVR脱机下载机(量产神器)带pc上位机和stm32下位机源码

  [复制链接]
ID:125153 发表于 2017-8-7 08:27 | 显示全部楼层 |阅读模式
自制的AVR离线下载器,使用的STM32F103C8T6单片机,通过上位机,发送hex文件,然后存在SD卡中,下位机带有文件系统,也可以通过电脑,按一定的格式,直接复制在SD当中。
上位机界面:
0.png

上位机源码:
0.png

0.png

stm32单片机下位机源程序如下:
  1. /*******************************************************************
  2. *
  3. *        模块名称 :         程序脚本
  4. *        文件名称 :  main.c
  5. *        版    本 :  V1.0
  6. *        说    明 :  硬件底层驱动程序集合
  7. *   芯    片 : STM32F103C8T6(48个外围引脚,64K Flash,LQFP封装,20K SRAM)

  8. *----------------修改记录------------------
  9. *   版 本 号 :  
  10. *   修改日期 :   
  11. *   作    者 :   ChenLin
  12. *        说    明 :   
  13. *
  14. ********************************************************************/
  15. #include "main.h"
  16. #include "spi.h"
  17. #include "AVR_Download.h"
  18. #include "sd.h"
  19. #include "HMI_Display.h"

  20. #define BOARD_TEST    //打开板子测试
  21. #define BEEP   PAout(9)

  22. /* 文件系统相关定义 ---------------------------------------------------------*/
  23. ///////////////////////////////////////////////////
  24. #define READ_TEST

  25.         FATFS fs;// Work area (file system object) for logical drive
  26.         FRESULT res;// FatFs function common result code
  27.         FIL fsrc, fdst;      // file objects
  28.         BYTE buffer[512]; // file copy buffer
  29.         UINT br, bw;         // File R/W count
  30.         DIR Folder;
  31.         unsigned char w_buffer[]={"test\r\n"};//演示写入文件
  32.         const char folder_name[] = {"/system"}; //文件夹名字
  33.         char file_path[FILE_LONG];//文件路径
  34.         char newfile_path[FILE_LONG];//新文件路径,改文件名用
  35. #ifdef READ_TEST
  36.         unsigned char r_buffer[512];//演示读入文件
  37. #endif
  38. ////////////////////////////////////////////////////

  39. int T1,T2,T3;
  40. /***************************************************************************
  41. ;** 函数名称: void RCC_Configuration(void)
  42. ;** 功能描述: RCC时针配置
  43. ;** 输入参数:
  44. ;** 返 回 值:
  45. ;** 全局变量:
  46. ;** 调用模块:
  47. ;** 作   者:   ChenLin
  48. ;** 日   期:   2017-1-13
  49. ;** 修改原因:
  50. ;** 说    明:
  51. ;***************************************************************************/
  52. void RCC_Configuration(void)
  53. {
  54.           RCC_DeInit();                                                                                 //初始化为缺省值
  55.         RCC_HSEConfig(RCC_HSE_ON);                                                         //使能外部的高速时钟
  56.         while(RCC_GetFlagStatus(RCC_FLAG_HSERDY)==RESET);         //等待外部高速时钟就绪

  57.         FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);//Enable Prefetch Buffer
  58.         FLASH_SetLatency(FLASH_Latency_2);                                         //Flash 2 wait state

  59.         RCC_HCLKConfig(RCC_SYSCLK_Div1);
  60.         RCC_PCLK2Config(RCC_HCLK_Div1);                                  //PCLK2=HCLK
  61.         RCC_PCLK1Config(RCC_HCLK_Div2);                                  //PCLK2=HCLK/2
  62.         RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);  //PLLCLK=8MHZ*9=72MH
  63.         RCC_PLLCmd(ENABLE);                                   //ENABLE PLLCLK
  64.         while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET);          //Wait till PLLCLK is ready
  65.         RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);                          //Set PLL as system clock
  66.         while(RCC_GetSYSCLKSource() != 0x08);                 //等待直到PLLCLK为系统时钟

  67.         RCC->CR |= (uint32_t)0x00080000;                                          //打开CSS(时钟监视系统)
  68.         //***********打开相应的外设************//

  69.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
  70.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
  71.         //SystemInit();  //全部外部时钟;        固件库默认

  72. }
  73. /***************************************************************************
  74. ;** 函数名称: void testProgram()
  75. ;** 功能描述: 用来测试板子的好坏,一输入对应一输出
  76. ;** 输入参数:
  77. ;** 返 回 值:
  78. ;** 全局变量:
  79. ;** 调用模块:
  80. ;** 作   者:   ChenLin
  81. ;** 日   期:   2017-1-13
  82. ;** 修改原因:
  83. ;** 说    明:
  84. ;***************************************************************************/
  85. void testProgram()
  86. {
  87.          if(!S1)
  88.         OUT1 = ON;
  89.     else
  90.         OUT1 = OFF;

  91.     if(!S2)
  92.         OUT2 = ON;
  93.     else
  94.         OUT2 = OFF;

  95.     if(!S3)
  96.         OUT3 = ON;
  97.     else
  98.         OUT3 = OFF;

  99.     if(!S4)
  100.         OUT4 = ON;
  101.     else
  102.         OUT4 = OFF;

  103.     if(!S5)
  104.         OUT5 = ON;
  105.     else
  106.         OUT5 = OFF;

  107.     if(!S6)
  108.         OUT6 = ON;
  109.     else
  110.         OUT6 = OFF;

  111.     if(!S7)
  112.         OUT7 = ON;
  113.     else
  114.         OUT7 = OFF;

  115.     if(!S8)
  116.         OUT8 = ON;
  117.     else
  118.         OUT8 = OFF;

  119.     if(!S9)
  120.         OUT9 = ON;
  121.     else
  122.         OUT9 = OFF;
  123.     if(!S10)
  124.         OUT10 = ON;
  125.     else
  126.         OUT10 = OFF;

  127.     if(!S11)
  128.         OUT11 = ON;
  129.     else
  130.         OUT11 = OFF;

  131.     if(!S12)
  132.         OUT12 = ON;
  133.     else
  134.         OUT12 = OFF;

  135.     if(!S13)
  136.         OUT13 = ON;
  137.     else
  138.         OUT13 = OFF;

  139.     if(!S14)
  140.         OUT14 = ON;
  141.     else
  142.         OUT14 = OFF;

  143.     if(!S15)
  144.         OUT15 = ON;
  145.     else
  146.         OUT15 = OFF;

  147.     if(!S16)
  148.         OUT16 = ON;
  149.     else
  150.         OUT16 = OFF;
  151.                
  152. }

  153. /***************************************************************************
  154. ;** 函数名称: void Get_File_Path(char *pp)
  155. ;** 输入参数: 得到文件路么,把文件名和文件夹名合成一个路径
  156. ;** 返 回 值:
  157. ;** 全局变量:
  158. ;** 调用模块:
  159. ;** 作   者:   ChenLin
  160. ;** 日   期:   2017-7-26
  161. ;** 修改原因:
  162. ;** 说    明:
  163. ;***************************************************************************/
  164. void Get_File_Path(char *path,char *pp)
  165. {
  166.         u8 i = 0;
  167.         char file_att[] = ".txt";//文件属性
  168.         //清空数组
  169.         for(i = 0;path[i] != 0;i++)
  170.         {
  171.                 path[i] = 0;
  172.         }
  173.         
  174.         //加入文件夹名字
  175.         for(i = 0;folder_name[i] != 0;i++)
  176.         {
  177.                 *path++ = folder_name[i];
  178.         }
  179.         *path++ = '/';
  180.         
  181.         //加入文件名字
  182.         while((*pp != '\r') && (*pp != '\n') && (*pp != '\0'))
  183.         {
  184.                 *path++ = *pp++;
  185.         }
  186.         //加入文件属性
  187.         for(i = 0;file_att[i] != 0;i++)
  188.         {
  189.                 *path++ = file_att[i];
  190.         }
  191.         *path = 0;
  192. }

  193. /***************************************************************************
  194. ;** 函数名称: void FATFS_Init(void)
  195. ;** 输入参数: FATFS文件系统相关初始化
  196. ;** 返 回 值:
  197. ;** 全局变量:
  198. ;** 调用模块:
  199. ;** 作   者:   ChenLin
  200. ;** 日   期:   2017-7-22
  201. ;** 修改原因:
  202. ;** 说    明:
  203. ;***************************************************************************/
  204. void FATFS_Init()
  205. {
  206.         DIR Folder;
  207.         char file_name[] = "test1";
  208.         FIL *file = &fsrc;
  209.         u32 offset = 0;
  210.         disk_initialize(0);
  211.         res = f_mount(&fs,"0:",1);
  212.         res = f_mkdir(folder_name);//创建一个文件夹        
  213.         res = f_opendir(&Folder,folder_name);
  214.         Get_File_Path(file_path,file_name);        //得到文件路径
  215.         
  216.         res=f_open(&fsrc,file_path,FA_CREATE_ALWAYS | FA_WRITE |FA_READ);
  217.         if(res == FR_OK)
  218.         {
  219.                 printfU3("打开文件成功\r\n");
  220.         }
  221.         else if(res == FR_NO_FILE)
  222.         {
  223.                 printfU3("找不到该文件\r\n");
  224.         }
  225.         else if(res == FR_NO_PATH)
  226.         {
  227.                 printfU3("找不到该路径\r\n");
  228.         }
  229.         else if(res == FR_INVALID_NAME)
  230.         {
  231.                 printfU3("文件名无效\r\n");
  232.         }
  233.         else if(res == FR_INVALID_DRIVE)
  234.         {
  235.                 printfU3("驱动器号无效\r\n");
  236.         }
  237.         else if(res == FR_NOT_READY )
  238.         {
  239.                 printfU3("驱动器中没有存储介质\r\n");
  240.         }
  241.         else if(res == FR_NO_FILESYSTEM )
  242.         {
  243.             printfU3("磁盘上没有有效地FAT卷。\r\n");
  244.         }
  245.         
  246.         res = f_write(file, &w_buffer, strlen((char*)w_buffer), &bw);
  247.         offset+=bw;
  248.     f_lseek(file,offset);
  249.         res = f_write(file, "chenlin\r\n", 10, &bw);
  250.         if(res == FR_OK )
  251.         {
  252.                 printfU3("写入成功!\r\n");
  253.         }
  254.         else
  255.         {
  256.                 printfU3("写入失败!\r\n");
  257.         }
  258.         
  259.         res=f_close(&fsrc);
  260.         
  261.         if(res == FR_OK )
  262.         {
  263.                 printfU3("关闭成功!\r\n");
  264.         }
  265.         else
  266.         {
  267.                 printfU3("关闭失败!\r\n");
  268.         }
  269.         
  270. #ifdef READ_TEST        
  271. //        f_unlink(file_path);//删除文件
  272.         res = f_opendir(&Folder,folder_name);
  273.         res=f_open(&fsrc,file_path,FA_READ);
  274.         f_gets((char*)r_buffer,32,&fsrc);
  275.         sprintfU3("r=%s\r\n",r_buffer);        
  276.         offset = strlen((char*)r_buffer);
  277.         f_gets((char*)r_buffer,32,&fsrc);
  278.         sprintfU3("r=%s\r\n",r_buffer);        
  279.         res=f_close(&fsrc);
  280. #endif
  281.         
  282. }

  283. /***************************************************************************
  284. ;** 函数名称: void buttonFunction()
  285. ;** 功能描述: 三个独立按钮功能程序,按钮实现上下翻页
  286. ;** 输入参数:
  287. ;** 返 回 值:
  288. ;** 全局变量:
  289. ;** 调用模块:
  290. ;** 作   者:   ChenLin
  291. ;** 日   期:   2017-7-27
  292. ;** 修改原因:
  293. ;** 说    明:
  294. ;***************************************************************************/
  295. void buttonFunction()
  296. {
  297.         
  298.         if(S5 && S9)
  299.                 p->flag[2] = false;
  300.         if(p->flag[2] == false)
  301.         if(!S5 && !S9) //同时按下S5和S9开关蜂鸣器
  302.         {
  303.                 p->flag[2] = true;
  304.                 p->LockBeep = ~(p->LockBeep);
  305.                 if(p->LockBeep == true)
  306.                 {
  307.                         HMISends("t9.txt=\"蜂鸣器失效\"");
  308.                         HMISendb(0xff,3);
  309.                         HMISends("t9.bco=65504");//控件颜色为黄色
  310.                         HMISendb(0xff,3);
  311.                         HMISends("vis t9,1");
  312.                         HMISendb(0xff,3);
  313.                         delay_Nms(1000);
  314.                         HMISends("vis t9,0");
  315.                         HMISendb(0xff,3);
  316.                 }
  317.                 else
  318.                 {
  319.                         HMISends("t9.txt=\"蜂鸣器已打开\"");
  320.                         HMISendb(0xff,3);
  321.                         HMISends("t9.bco=2024");//控件颜色为亮绿色
  322.                         HMISendb(0xff,3);
  323.                         HMISends("vis t9,1");
  324.                         HMISendb(0xff,3);
  325.                         delay_Nms(1000);
  326.                         HMISends("vis t9,0");
  327.                         HMISendb(0xff,3);
  328.                 }
  329.                 return;
  330.         }
  331.         
  332.         if(p->flag[1] == false)
  333.         if(p->LastPage)  //上一页
  334.         {
  335.                 p->flag[1] = true;
  336.                 Read_Num = Read_Num - 1;
  337.                 if(Read_Num <= 0)
  338.                 {
  339.                         Read_Num = 100;
  340.                 }
  341.                 AVR.flag1 = true;  //加标志
  342.                 AVR.flashUpdate = false; //刷新flash标志
  343.                 return;
  344.         }
  345.         
  346.         if(p->NextPage)  //下一页
  347.         {
  348.                 while(!S5)
  349.                 {
  350.                         keyScan();        
  351.                         if(p->ProgramStatus == true) //是长按
  352.                         {
  353.                                 return;
  354.                         }
  355.                 }
  356.                 Read_Num = Read_Num + 1;
  357.                 if(Read_Num > 100)
  358.                 {
  359.                         Read_Num = 1;
  360.                 }
  361.                 AVR.flag1 = false;
  362.                 AVR.flashUpdate = false; //刷新flash标志,fasle有效
  363.         }
  364.         
  365. }

  366. void BeepControl(u8 n)
  367. {
  368.         if((p->LockBeep == false)&&(n == ON))
  369.         {
  370.                 BEEP = ON;
  371.                 delay_Nms(400);
  372.                 BEEP = OFF;
  373.         }
  374.         else
  375.                 BEEP = OFF;
  376. }

  377. int main()                                                   
  378. {               
  379.     RXstructure *p3 = &usart3_buf;
  380.         RXstructure *p2 = &usart2_buf;
  381.         uint32_t sdCapacity;
  382.         u8 i = 0;
  383.     delay_Nms(500);  //上电延时
  384.         RCC_Configuration();
  385.         GPIO_Configuration();
  386.         IIC_Configuration();
  387.         TIM3_Configuration(35999, 10, 5);    //定时5ms  
  388.         TIM4_Configuration(35999, 10, 5);    //定时5ms  
  389.         USART3_Configuration(115200);
  390.         USART2_Configuration(9600);

  391.         SPI1_Config();  //与AVR通信
  392.         SPI2_Config();  //SD卡通信
  393.         
  394.         printfU3("communication finish\r\n");
  395.         while(SD_Init())  //SD卡初始化
  396.         {
  397.                 i++;
  398.                 if(i>10)
  399.                 {
  400.                         HMISends("page no SD Card");   
  401.                         HMISendb(0xff,3);
  402.                         while(SD_Init());  //SD卡初始化
  403.                 }
  404.         }
  405.         
  406.         printfU3("SD卡初始化成功\r\n");
  407.         SD_ReadCapacity(&sdCapacity);
  408.         sprintfU3("SD卡扇区数:%d ",sdCapacity);
  409.         if(SD_TYPE == SD_TYPE_V2HC)
  410.                 printfU3("This is High Capacity SD Memory Card\r\n");
  411.         else if(SD_TYPE == SD_TYPE_V2)
  412.                 printfU3("This is Standard Capacity SD Memory Card\r\n");
  413.         
  414.         HMI_Init();
  415.         
  416.         FATFS_Init();   //FATFS文件系统初始化

  417.         while(1)
  418.         {        
  419.                 keyScan();
  420.                 buttonFunction();//按键功能
  421.                 if(p->ProgramStatus)
  422.                 {
  423.                         AVR.programFlag = ~AVR.programFlag;   
  424.                         
  425.                         if(AVR.programFlag==true)
  426.                         {
  427.                                 printfU3("enter program status\r\n");
  428.                                 HMISends("page program");
  429.                                 HMISendb(0xff,3);
  430.                         
  431.                         }
  432.                         else
  433.                         {
  434.                                 printfU3("quit program status\r\n");
  435.                                 HMISends("page main");
  436.                                 HMISendb(0xff,3);
  437.                                 Read_Num=IIC_Read_Data(num_Addr); //读保存的镜像号
  438.                                 AVR.flashUpdate = false;
  439.                         }
  440.                         AVR.flag2 = false; //如果没找到flash,再进入一次HMI显示no flash操作
  441.                         BeepControl(ON);
  442.                         while(!S5);
  443.                         delay_Nms(10);
  444.                 }           
  445.                
  446.                 //编程状态
  447.                 if(AVR.programFlag == true)
  448.                 {
  449.                         
  450.                         if(p3->flagRec)
  451.                         {
  452.                                 if(p3->data[0] == ':')       //接收到的是hex文件
  453.                                         Save_Data_To_Flash();
  454.                                 else                         //接收到的是命令
  455.                                 {
  456.                                         usart3Function();
  457. ……………………

  458. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
AVR离线下载器-上位机.zip (100.88 KB, 下载次数: 184)

评分

参与人数 1黑币 +100 收起 理由
admin + 100 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:311665 发表于 2018-4-19 15:51 | 显示全部楼层
楼主,我想自制这个编程器,请问有电路图吗?共享一下可以吗?
还有就是这个上位机是用什么平台写的?看文件不是VB6写的,是VC吗?还是PHP?
硬件做好后直接烧录里面那个HEX文件即可使用了对吧?还要做其它设置吗?
回复

使用道具 举报

ID:38212 发表于 2017-9-9 18:41 | 显示全部楼层
东西不错,学习了,  谢谢分享!
回复

使用道具 举报

ID:38212 发表于 2017-9-9 18:42 | 显示全部楼层
东西不错!学习了。 谢谢分享!
回复

使用道具 举报

ID:43554 发表于 2017-9-13 11:19 | 显示全部楼层
很好的设计,帮顶了!
回复

使用道具 举报

ID:224923 发表于 2017-9-18 14:37 | 显示全部楼层
很好的设计,值得研究。谢谢楼主共享。
回复

使用道具 举报

ID:272158 发表于 2018-1-6 13:46 | 显示全部楼层
有没有图纸呀,提供一下学习学习。
回复

使用道具 举报

ID:108964 发表于 2018-5-1 22:45 | 显示全部楼层
基于STM32的AVR单片机下载机!!!
回复

使用道具 举报

ID:277202 发表于 2018-5-11 08:28 | 显示全部楼层
mark 学习
回复

使用道具 举报

ID:48413 发表于 2018-5-15 08:02 | 显示全部楼层
正需要那,谢谢你
回复

使用道具 举报

ID:282291 发表于 2018-6-8 15:53 | 显示全部楼层
不错
回复

使用道具 举报

ID:380992 发表于 2018-7-30 18:30 | 显示全部楼层
正有需要,謝謝你
回复

使用道具 举报

ID:420316 发表于 2018-11-3 23:35 | 显示全部楼层
这个厉害了,我就是因为搜这个资料找到这里的,感谢,想学着做一款离线烧录
回复

使用道具 举报

ID:399144 发表于 2019-1-22 14:22 | 显示全部楼层
有没有电路图呀,想学习一下
回复

使用道具 举报

ID:161616 发表于 2019-1-23 09:16 | 显示全部楼层
谢谢,学习了
回复

使用道具 举报

ID:471573 发表于 2019-1-23 15:45 | 显示全部楼层
好东西!!!
回复

使用道具 举报

ID:357775 发表于 2019-11-4 10:18 | 显示全部楼层
下位机源码没上传啊
回复

使用道具 举报

ID:517951 发表于 2019-12-12 17:44 | 显示全部楼层
楼主,好文章,学习啦
回复

使用道具 举报

ID:824599 发表于 2020-9-29 15:14 | 显示全部楼层
请问适用于STM脱机下载机吗?
回复

使用道具 举报

ID:517951 发表于 2020-11-15 17:45 | 显示全部楼层
不错,值得学习。51hei有你更精彩!!
回复

使用道具 举报

ID:271449 发表于 2021-5-1 14:12 | 显示全部楼层
上位机看不懂,只能看看下位机的了
回复

使用道具 举报

ID:87000 发表于 2021-11-10 13:39 | 显示全部楼层
没有原理图,不能仿制
回复

使用道具 举报

ID:23303 发表于 2023-4-18 10:13 | 显示全部楼层
我就是因为搜这个资料找到这里的,感谢,想学着做一款离线烧录
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表