用两个atmega48(或atmega8)制作的通用编程器

2023年重新编辑一下我这篇文章,文章标题太夸大,我只实现了一种存储器的编程。还有就是我十几年后才发现有一个扩展芯片PCF8574可以代替一个atmega48,才1块多钱。以下是2011年原文。

主48  通过串口和电脑相连

从48代替74373锁存器

编程对象是w39v040。

程序有待改善 ,检测写入(或擦除)完成的程序用延时程序代替的。

主48 pb口为双向口,发送给从48锁存数据,发送和接收待编程的存储器的数据。

主48 pc口是控制线 oe、we、r/c、reset ,pc5接到从48的pc5当做ALE线。

主48 pd口为6位地址。

从48 pb口为输入,接收地址。

从48 pd口为地址输出。

单片机用的汇编语言,电脑端程序用的c语言。

从48的程序:

.include "m48def.inc"
;变更pinc 6 为5  因为6是复位脚
reset:
 ldi r16,0;端口b设为输入
 out DDRB,r16 
 ldi r16,(1<<PB4)|(1<<PB3)|(1<<PB2)|(1<<PB1)|(1<<PB0);端口pc6 pc5设为输入
 out DDRC,r16
 ldi r16,0xff;端口d设为输出
 out DDRD,r16

;初始化完毕
lp1:sbis PINC,5    ;等待高电平到来
 rjmp lp1
down:
 sbic PINC,5  ;等待低电平
 rjmp down

 in r20,PINB

; sbic PINC,5   ;判断pc5 如果是0就输出到pd  是1输出到pc
; rjmp outc

 out PORTD,r20
 rjmp lp1
outc:
 out PORTC,r20
 rjmp lp1

主48:

.include "m48def.inc"

reset:
ldi r16,0; 设置波特率
ldi r17,8
ldi r30,UBRR0H
ldi r31,0;
st z, r16
ldi r30,UBRR0L
ldi r31,0;
st z, r17

ldi r16, (1<<RXEN0)|(1<<TXEN0);|(U2X0); 接收器与发送器使能
ldi r30,UCSR0B
ldi r31,0;
st z, r16

ldi r16,0xff;端口d设为输出
out DDRD,r16

ldi r16,0xff;端口c设为输出
;out DDRC,r16
sbi DDRC,0 sbi DDRC,1 sbi DDRC,2 sbi DDRC,3 sbi DDRC,4 sbi DDRC,5 cbi DDRC,6  ; 因为pc6 接着slave48的复位脚

ldi r16,0x00;端口b设为输入
out DDRB,r16

ldi r16,0xff
out  PORTB, r16

ldi r16,0x0
out  PORTC, r16

sbi PORTC,0     ;OE
sbi PORTC,1     ;WE
sbi PORTC,2     ;R/C
sbi PORTC,3  ;RST
sbi PORTC,4  ;IC 没有
cbi PORTC,5  ;slave48锁存
;sbi PORTC,6  ;slave48复位脚为1


cbi PORTC,3
nop
nop        ;复位待编程芯片
nop
sbi PORTC,3
;初始化完毕
ldi r19,0x23
rcall  send
;------------------------------------------------------------------------------------

xunhuan:
 rcall  recive
 mov r19,r18
 rcall  send
rjmp xunhuan

read:
 ldi r25,0
loop4:
 ldi r24,0 
loop3:
 ldi r23,0
loop2:
 ldi r22,0   
loop:

mov r0,r22
mov r1,r23
mov r2,r24
mov r3,r25
rcall readflash

inc r22
cpi r22,64
brlo loop

inc r23
cpi r23,32
brlo loop2
/*
inc r24
cpi r24,64
brlo loop3

inc r25
cpi r25,4
brlo loop4
*/
ret

                       ;r20=tmp
send:
 ldi r30,UCSR0A     ;r19  发送
 ldi r31,0
 ld r20,z
 sbrs r20,UDRE0;;;;;不能为TXC0,如果是txc0可能需要用sbrc
 rjmp send

 ldi r30,UDR0
 ldi r31,0;
 st z, r19
 ret

;------------------------------------------------------------------------------------------------
recive:
 ldi r30,UCSR0A      ;r18 接收
 ldi r31,0
 ld r20,z
 sbrs r20,RXC0
 rjmp recive

 ldi r30,UDR0
 ldi r31,0
 ld r18,z
 cpi r18,'/'   ;如果不是转义符就ret
 brne ret_rec

recive2:
 ldi r30,UCSR0A      ;r18 接收
 ldi r31,0
 ld r20,z
 sbrs r20,RXC0
 rjmp recive2

 ldi r30,UDR0
 ldi r31,0
 ld r18,z 
 cpi r18,'/'   ;如果是转义符就ret
 breq ret_rec 

 cpi r18,'0'   ;如果是r就reset
 brne next
 ldi r30,low(reset)
 ldi r31,high(reset)
 ijmp 
next:
 cpi r18,'i'   ;如果是i就idread
 brne next2
 ldi r30,low(idread)
 ldi r31,high(idread)
 icall
 rjmp ret_rec
next2:
 cpi r18,'w'  ;如果是w就write
 brne next3
 ldi r30,low(write)
 ldi r31,high(write)
 icall
 rjmp ret_rec
next3:
 cpi r18,'r'  ;如果是r就read
 brne next4
 ldi r30,low(read)
 ldi r31,high(read)
 icall
 rjmp ret_rec
next4:
 cpi r18,'e'   ;如果是e就eraseflash
 brne ret_rec
 ldi r30,low(eraseflash)
 ldi r31,high(eraseflash)
 icall
ret_rec: 
 ret
;----------------------------------------------------------------------------------------------

write:
 ldi r25,0
aloop4:
 ldi r24,0 
aloop3:
 ldi r23,0
aloop2:
 ldi r22,0   
aloop:

ldi r16,0x15
mov r0,r16
ldi r16,0x15
mov r1,r16
ldi r16,0xa
mov r2,r16
ldi r16,0
mov r3,r16
ldi r16,0xaa
mov r4,r16
rcall writeflash

ldi r16,0x2a
mov r0,r16
ldi r16,0xa
mov r1,r16
ldi r16,0x5
mov r2,r16
ldi r16,0
mov r3,r16
ldi r16,0x55
mov r4,r16
rcall writeflash

ldi r16,0x15
mov r0,r16
ldi r16,0x15
mov r1,r16
ldi r16,0xa
mov r2,r16
ldi r16,0
mov r3,r16
ldi r16,0xa0
mov r4,r16
rcall writeflash

rcall recive
mov r0,r22
mov r1,r23
mov r2,r24
mov r3,r25
mov r4,r18
rcall writeflash

ldi r16,0;;;;;;;;;;;;;;延时
ldi r17,100
i:
inc r16
cpse r16,r17
rjmp i


ldi r19, 67   ;发送
rcall send

inc r22
cpi r22,64
brlo aloop

inc r23
cpi r23,32
brlo aloop2
/*
inc r24
cpi r24,64
brlo aloop3

inc r25
cpi r25,4
brlo aloop4
*/

 ret


eraseflash:
ldi r16,0x15
mov r0,r16
ldi r16,0x15
mov r1,r16
ldi r16,0xa
mov r2,r16
ldi r16,0
mov r3,r16
ldi r16,0xaa
mov r4,r16
rcall writeflash

ldi r16,0x2a
mov r0,r16
ldi r16,0xa
mov r1,r16
ldi r16,0x5
mov r2,r16
ldi r16,0
mov r3,r16
ldi r16,0x55
mov r4,r16
rcall writeflash

ldi r16,0x15
mov r0,r16
ldi r16,0x15
mov r1,r16
ldi r16,0xa
mov r2,r16
ldi r16,0
mov r3,r16
ldi r16,0x80
mov r4,r16
rcall writeflash

ldi r16,0x15
mov r0,r16
ldi r16,0x15
mov r1,r16
ldi r16,0xa
mov r2,r16
ldi r16,0
mov r3,r16
ldi r16,0xaa
mov r4,r16
rcall writeflash

ldi r16,0x2a
mov r0,r16
ldi r16,0xa
mov r1,r16
ldi r16,0x5
mov r2,r16
ldi r16,0
mov r3,r16
ldi r16,0x55
mov r4,r16
rcall writeflash

ldi r16,0x15
mov r0,r16
ldi r16,0x15
mov r1,r16
ldi r16,0xa
mov r2,r16
ldi r16,0
mov r3,r16
ldi r16,0x10
mov r4,r16
rcall writeflash
 ret

idread:
ldi r16,0x15
mov r0,r16
ldi r16,0x15
mov r1,r16
ldi r16,0xa
mov r2,r16
ldi r16,0
mov r3,r16
ldi r16,0xaa
mov r4,r16
rcall writeflash

ldi r16,0x2a
mov r0,r16
ldi r16,0xa
mov r1,r16
ldi r16,0x5
mov r2,r16
ldi r16,0
mov r3,r16
ldi r16,0x55
mov r4,r16
rcall writeflash

ldi r16,0x15
mov r0,r16
ldi r16,0x15
mov r1,r16
ldi r16,0xa
mov r2,r16
ldi r16,0
mov r3,r16
ldi r16,0x90
mov r4,r16
rcall writeflash

ldi r16,0
ldi r17,100
ai:
inc r16
cpse r16,r17
rjmp ai


ldi r16,0x0
mov r0,r16
ldi r16,0x0
mov r1,r16
ldi r16,0x0
mov r2,r16
ldi r16,0
mov r3,r16
rcall readflash

ldi r16,0x1
mov r0,r16
ldi r16,0x0
mov r1,r16
ldi r16,0x0
mov r2,r16
ldi r16,0
mov r3,r16
rcall readflash

ldi r16,0xf0
mov r4,r16
rcall writeflash

 ret

writeflash:
 ldi r16,0xff ;端口b设为输出
 out DDRB,r16 
 
 lsl r0
 lsl r0
 out  PORTD, r0

 sbi PORTC,5 
 out  PORTB,r1
 nop nop nop nop ;等待slave48
 cbi PORTC,5 
 nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop
 cbi PORTC,2  
  
cbi PORTC,1;]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]

 lsl r2
 lsl r2
 out PORTD, r2

 sbi PORTC,5 
 out  PORTB,r3
 nop nop nop nop ;等待slave48
 cbi PORTC,5 
 nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop
 sbi PORTC,2
;----------------------------------------------------------------


 nop
 out PORTB,r4
 nop
 sbi PORTC,1

ret

readflash:
 ldi r16,0xff ;端口b设为输出
 out DDRB,r16 
 
 lsl r0
 lsl r0
 out  PORTD, r0

 sbi PORTC,5 
 out  PORTB,r1
 nop nop nop nop ;等待slave48
 cbi PORTC,5 
 nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop
 cbi PORTC,2  
  
///

 lsl r2
 lsl r2
 out PORTD, r2

 sbi PORTC,5 
 out  PORTB,r3
 nop nop nop nop ;等待slave48
 cbi PORTC,5 
 nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop
 sbi PORTC,2
;--------------------------------------------------------------
 ldi r16,0x00 ;端口b设为输入
 out DDRB,r16

 cbi PORTC,0;
 nop
 in  r19,pinb
 sbi PORTC,0

 rcall  send

 ret

电脑端软件:

#include <windows.h>
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
#include <stdio.h>
#include <winuser.h>
#include "resource.h"
#pragma comment( lib, "WINMM.LIB" )
HWND  hwnd;
HANDLE hfile,hCom,hfile2,hfile_jieshou;
DWORD  status,statusA;
UINT wTimerRes_1ms=1;
UINT wAccuracy;
# define TIMER_ACCURACY 1
DWORD  aaa;
DWORD num;
SYSTEMTIME _time1;
char str[52],tmp[10];
DWORD wCount;
int i,ii,iii;
HINSTANCE hInst;
char c_path_recive[260],c_path_send[260];
char c_filename[260]="down";
OPENFILENAME openfilename,openfilename2;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)

 hInst=hInstance;
 DialogBoxParam(hInstance, MAKEINTRESOURCE (IDD_DIALOG1),0, (DLGPROC) WndProc,NULL); 
 return 0;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

 switch (message)
 {
 case WM_INITDIALOG:  
  hwnd=hWnd;   
  hCom=CreateFile("COM3", GENERIC_READ|GENERIC_WRITE, 0,NULL , OPEN_EXISTING, 0, NULL);
  if(hCom==(HANDLE)-1)MessageBox(0,"打开com失败",0,0); 
   hfile2=CreateFile("c:\\lo.txt", GENERIC_WRITE|GENERIC_READ ,FILE_SHARE_READ|FILE_SHARE_WRITE ,0,CREATE_ALWAYS,0,0);
   if(hfile2==(HANDLE)-1)MessageBox(0,"打开文件失败",0,0);    

  SetDlgItemText(hwnd,IDC_EDIT1,"c:\\jieshou.txt"); 
  SetDlgItemText(hwnd,IDC_EDIT2,"c:\\fasong"); 
  
  
  
  DCB dcb;
  dcb.BaudRate = 57600; //波特率为9600
  dcb.ByteSize = 8; //数据位数为7位
  dcb.Parity = 0; //偶校验
  dcb.StopBits = 1; //两个停止位
  
  
  if (!SetCommState(hCom, &dcb))
  {
   //MessageBox(0,"串口设置出错!",0,0);
  } 
  SetupComm(hCom, 1024, 1024);
  PurgeComm(hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR); 
  
  
  break;
  
  
 case WM_COMMAND: 
  switch (LOWORD(wParam))
  {
  case (RECIVE):
   GetDlgItemText(hwnd,IDC_EDIT1,c_filename,260);
   hfile_jieshou=CreateFile(c_filename, GENERIC_WRITE|GENERIC_READ ,FILE_SHARE_READ|FILE_SHARE_WRITE ,0,CREATE_ALWAYS,0,0);
   if(hfile_jieshou==(HANDLE)-1)MessageBox(0,"打开文件失败",0,0);
   
   WriteFile(hCom,"/r",2,&num,0);  
   
   i=0;
   do
   {
    i++;
    if(i>0x800)break;
    ReadFile(hCom,str,1, &wCount, NULL);    
    if(wCount > 0)
    {
     WriteFile(hfile_jieshou,str,wCount,&num,0);
    }
   }while(1);
   SetDlgItemText(hwnd,IDC_EDIT,"recived");
   ReadFile(hCom,tmp,1, &wCount, NULL);
   CloseHandle(hfile_jieshou);
   break;
  case (SEND)://-------------------------------------------------
   GetDlgItemText(hwnd,IDC_EDIT2,c_filename,260);
   hfile=CreateFile(c_filename, GENERIC_WRITE|GENERIC_READ ,FILE_SHARE_READ|FILE_SHARE_WRITE ,0,OPEN_ALWAYS,0,0);
   if(hfile==(HANDLE)-1)MessageBox(0,"打开文件失败",0,0);   
   
   WriteFile(hCom,"/w",2,&num,0);
   do
   {     
    ReadFile(hfile,str, 1, &wCount, NULL);
    if(str[0]==0x2f)
    {WriteFile(hCom,str,1,&num,0);}    
    if(wCount > 0)
    {
     WriteFile(hCom,str,wCount,&num,0);
     ReadFile(hCom,tmp,1, &num, NULL);
    }
   }while(wCount!=0);
   ReadFile(hCom,tmp,1, &wCount, NULL);
   SetDlgItemText(hwnd,IDC_EDIT,"sended");
   CloseHandle(hfile);
   break;
  case (ERASE)://-----------------------------------------------------
   WriteFile(hCom,"/e",2,&num,0); 
   ReadFile(hCom,tmp,1, &wCount, NULL);
   ii=60;
   SetTimer(hwnd,1,1000,0);
   char bufferx[50];
   _gcvt(ii, 20, bufferx );
   SetDlgItemText(hwnd,IDC_EDIT,bufferx);
   break;
  case (RESET):
   WriteFile(hCom,"/0",2,&num,0);
   ReadFile(hCom,str,1, &wCount, NULL);
   str[1]=0;
   SetDlgItemText(hwnd,IDC_EDIT,str);
   break;
  case (IDREAD):
   WriteFile(hCom,"/i",2,&num,0);

   ReadFile(hCom,tmp,1, &wCount, NULL);
   str[0]=tmp[0];
   ReadFile(hCom,tmp,1, &wCount, NULL);
   str[1]=tmp[0];
   ReadFile(hCom,tmp,1, &wCount, NULL);
   str[2]=tmp[0];

/*   

iii=3;
wCount=0;
//Sleep(1);
do
{
ReadFile(hCom,str,iii, &wCount, NULL);
WriteFile(hfile2,str,iii, &num, 0);
char bufferxx[50];
    _gcvt(ii, 20, bufferxx );
WriteFile(hfile2, bufferxx,2, &num, 0);
iii=iii-wCount;
if(i==0)break;

}
while(1);
*/

   str[3]=0;
   SetDlgItemText(hwnd,IDC_EDIT,str);
   break;
  case (R):
   openfilename.lStructSize=sizeof(openfilename);
   openfilename.hwndOwner=hwnd;
   openfilename.hInstance=hInst;
   openfilename.lpstrFilter="all file\0*.*\0\0";
   openfilename.lpstrFile=c_path_recive;
   openfilename.nMaxFile=260;
   openfilename.Flags=OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_LONGNAMES | OFN_EXPLORER | OFN_HIDEREADONLY ;
   openfilename.lpstrTitle="recive";
   GetOpenFileName(&openfilename);
   SetDlgItemText(hwnd,IDC_EDIT1,c_path_recive);
   break;
  case (S):
   openfilename2.lStructSize=sizeof(openfilename2);
   openfilename2.hwndOwner=hwnd;
   openfilename2.hInstance=hInst;
   openfilename2.lpstrFilter="all file\0*.*\0\0";
   openfilename2.lpstrFile=c_path_send;
   openfilename2.nMaxFile=260;
   openfilename2.Flags=OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_LONGNAMES | OFN_EXPLORER | OFN_HIDEREADONLY ;
   openfilename2.lpstrTitle="recive";
   GetOpenFileName(&openfilename2);
   SetDlgItemText(hwnd,IDC_EDIT2,c_path_send);
   break;
  }  
  break; 
  case WM_TIMER:
   switch (wParam)
   {
   case 1:
    ii--;
    if(ii<0)KillTimer(hwnd,1);
    char bufferxx[50];
    _gcvt(ii, 20, bufferxx );
    SetDlgItemText(hwnd,IDC_EDIT,bufferxx);
    break;
   }
   break;
   case WM_DESTROY:
    PostQuitMessage(0);
    break;
   case WM_CLOSE:
    EndDialog( hWnd,NULL) ;
    break;   
 } 
 return  FALSE;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值