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;
}