8051을 이용해서 스태핑모터를 구동하는 프로그램인데요c프로그램이 에러가 뜹니다.베이직으로 이용해서 컴에서 조저을하고 c언어는 8051보드에 있는 롬에 넣어서 사용하는 경우입니다. 구동방식은 전진,후진,좌회전,우회전 이런방식입니다.
베이직소스입니다.
Option Explicit
Private mRcv As String
Private mRcvBuf As String
Private Sub cboBaud_Click()
cmdClose.Enabled = True
If (MSComm1.PortOpen) Then
MSComm1.PortOpen = False
End If
MSComm1.CommPort = Mid(cboPort.Text, 4, 1)
MSComm1.Settings = cboBaud.Text & "," & Left(cboParity.Text, 1) & "," & cboData.Text & "," & cboStop.Text
MSComm1.InputLen = 0
MSComm1.PortOpen = True
End Sub
Private Sub cboData_Click()
cmdClose.Enabled = True
If (MSComm1.PortOpen) Then
MSComm1.PortOpen = False
End If
MSComm1.CommPort = Mid(cboPort.Text, 4, 1)
MSComm1.Settings = cboBaud.Text & "," & Left(cboParity.Text, 1) & "," & cboData.Text & "," & cboStop.Text
MSComm1.InputLen = 0
MSComm1.PortOpen = True
End Sub
Private Sub cboParity_Click()
cmdClose.Enabled = True
If (MSComm1.PortOpen) Then
MSComm1.PortOpen = False
End If
MSComm1.CommPort = Mid(cboPort.Text, 4, 1)
MSComm1.Settings = cboBaud.Text & "," & Left(cboParity.Text, 1) & "," & cboData.Text & "," & cboStop.Text
MSComm1.InputLen = 0
MSComm1.PortOpen = True
End Sub
Private Sub cboPort_Click()
cmdClose.Enabled = True
If (MSComm1.PortOpen) Then
MSComm1.PortOpen = False
End If
MSComm1.CommPort = Mid(cboPort.Text, 4, 1)
MSComm1.Settings = cboBaud.Text & "," & Left(cboParity.Text, 1) & "," & cboData.Text & "," & cboStop.Text
MSComm1.InputLen = 0
MSComm1.PortOpen = True
End Sub
Private Sub cboStop_Click()
cmdClose.Enabled = True
If (MSComm1.PortOpen) Then
MSComm1.PortOpen = False
End If
MSComm1.CommPort = Mid(cboPort.Text, 4, 1)
MSComm1.Settings = cboBaud.Text & "," & Left(cboParity.Text, 1) & "," & cboData.Text & "," & cboStop.Text
MSComm1.InputLen = 0
MSComm1.PortOpen = True
cmdOpen.Enabled = True
End Sub
Private Sub cmdClose_Click()
cmdClose.Enabled = False
If (MSComm1.PortOpen) Then
MSComm1.PortOpen = False
End If
cmdOpen.SetFocus
End
End Sub
Private Sub cmdl_Click()
MSComm1.Output = Chr(170)
'MSComm1.Output = Chr(170)
'MSComm1.Output = Chr(170)
MSComm1.Output = Chr(76) '아스키값 'L' 시리얼포트로 출력
End Sub
Private Sub cmdr_Click()
MSComm1.Output = Chr(170)
'MSComm1.Output = Chr(170)
'MSComm1.Output = Chr(170)
MSComm1.Output = Chr(82) '아스키값 'R' 시리얼포트로 출력
End Sub
Private Sub cmdOpen_Click()
cmdClose.Enabled = True
If (MSComm1.PortOpen) Then
MSComm1.PortOpen = False
End If
MSComm1.CommPort = Mid(cboPort.Text, 4, 1)
MSComm1.Settings = cboBaud.Text & "," & Left(cboParity.Text, 1) & "," & cboData.Text & "," & cboStop.Text
MSComm1.InputLen = 0
MSComm1.PortOpen = True
MSComm1.RThreshold = 1
End Sub
Private Sub cmdfront_Click() 'step motor front shift
'MSComm1.Output = Chr(170)
'MSComm1.Output = Chr(170)
MSComm1.Output = Chr(170)
MSComm1.Output = Chr(49) '아스키값 '1' 시리얼포트로 출력
End Sub
Private Sub cmdback_Click() 'step motor back shift
'MSComm1.Output = Chr(170)
'MSComm1.Output = Chr(170)
MSComm1.Output = Chr(170)
MSComm1.Output = Chr(50) '아스키값 '2' 시리얼포트로 출력
End Sub
Private Sub cmdright_Click() 'step motor right shift
'MSComm1.Output = Chr(170)
'MSComm1.Output = Chr(170)
MSComm1.Output = Chr(170)
MSComm1.Output = Chr(51) '아스키값 '3' 시리얼포트로 출력
End Sub
Private Sub cmdleft_Click() 'step motor left shift
'MSComm1.Output = Chr(170)
'MSComm1.Output = Chr(170)
MSComm1.Output = Chr(170)
MSComm1.Output = Chr(52) '아스키값 '4' 시리얼포트로 출력
End Sub
Private Sub cmdlf_Click() 'step motor left front shift
'MSComm1.Output = Chr(170)
'MSComm1.Output = Chr(170)
MSComm1.Output = Chr(170)
MSComm1.Output = Chr(53) '아스키값 '5' 시리얼포트로 출력
End Sub
Private Sub cmdrf_Click() 'step motor right front shift
'MSComm1.Output = Chr(170)
'MSComm1.Output = Chr(170)
MSComm1.Output = Chr(170)
MSComm1.Output = Chr(54) '아스키값 '6' 시리얼포트로 출력
End Sub
Private Sub cmdlb_Click() 'step motor left back shift
'MSComm1.Output = Chr(170)
'MSComm1.Output = Chr(170)
MSComm1.Output = Chr(170)
MSComm1.Output = Chr(55) '아스키값 '7 시리얼포트로 출력
End Sub
Private Sub cmdrb_Click() 'step motor right back shift
'MSComm1.Output = Chr(170)
'MSComm1.Output = Chr(170)
MSComm1.Output = Chr(170)
MSComm1.Output = Chr(56) '아스키값 '8' 시리얼포트로 출력
End Sub
Private Sub cmddis_Click() 'step motor auto control
'MSComm1.Output = Chr(170)
'MSComm1.Output = Chr(170)
MSComm1.Output = Chr(170)
MSComm1.Output = Chr(57) '아스키값 '9' 시리얼포트로 출력
End Sub
Private Sub Form_Load() '폼이 로드돼면
' 각 시리얼 세팅
cboPort.ListIndex = 0
cboBaud.ListIndex = 7
cboData.ListIndex = 4
cboParity.ListIndex = 2
cboStop.ListIndex = 0
If (MSComm1.PortOpen) Then '포트가 열려있으면
MSComm1.PortOpen = False '포트 개폐
End If
MSComm1.CommPort = Mid(cboPort.Text, 4, 1)
MSComm1.Settings = cboBaud.Text & "," & Left(cboParity.Text, 1) & "," & cboData.Text & "," & cboStop.Text
MSComm1.InputLen = 0
MSComm1.PortOpen = True
MSComm1.RThreshold = 1
End Sub
Private Sub MSComm1_OnComm()
mRcv = MSComm1.Input
'mRcvBuf = mRcv
txtin.Text = txtin.Text & mRcv 'txtln에 mRcv에 있는 데이터를 축척해서 출력
txtin.SelStart = 65535 '커서를 txtln에 데이터가 있는 맨아래에 위치
End Sub
c소스입니다.
#include "C:\Keil\C51\BIN\LBO\step\stepcon1\std51.h"
#include "C:\Keil\C51\BIN\LBO\step\stepcon1\LBO_HARD.h"
//#include <ctype.h> // function
#include <stdio.h> // I/O에 관련된 Prototype 선언
/****************************************/
/* function prototype */
/****************************************/
int i;
unsigned char st[4] = {0x01,0x02,0x04,0x08};
int a,b,c,d;
struct ring q; // for Communication q-buffer
uchar get_char;
/******************************************************************/
/************* 8255 ******************/
/******************************************************************/
unsigned char xdata PPI_A _at_ 0xC000; //A-Port Address
unsigned char xdata PPI_B _at_ 0xc001; //B-port Address
unsigned char xdata PPI_C _at_ 0xc002; //C-Port Address
unsigned char xdata PPI_CR _at_ 0xc003;
#define CW 0x80 //전체 출력 80 // 제어워드값이 1000 1001 A, B 포트는 출력. C포트는 입력89
void init_8255();
void front(); /*전진*/
void back();/*후진*/
void right();
void left();
void rf();
void lf();
void lb();
void rb();
void stepauto();
void autoright();
void autoleft();
void stop();
void delay(uint i); //지연함수
// Utility
//uchar xtoa_h(uchar _byteh); // Hex to ASCII Converter 상위 Nibble
//uchar xtoa_l(uchar _bytel); // Hex to ASCII Converter 하위 Nibble
void putbyte(char c); // 문자(文字) 출력
// make 2001.1130
void putstring(char *str); // Point 문자열 출력
// Utility
void init_serial(void); // 19200Bps setting
// Communication
void init_qbuffer(void); // q-buffer setup
bit check_pop(void); // check SBUF Point
/****************************************/
/* lcd function prototype */
/****************************************/
// Utility
uchar xtoa_h(uchar _byteh); // Hex to ASCII Converter 상위 Nibble
uchar xtoa_l(uchar _bytel); // Hex to ASCII Converter 하위 Nibble
// make 2001.1130
// Utility
void check_chip(void);
// Communication
//LCD
void LCD_goxy(unsigned char x, unsigned char y); // lcd display location
void LCD_string(uchar *s); // string print to LCD
void LCD_clr(void); // clear display DATA=0000 0001
void LCD_CMD_Write(unsigned char pass_value); // instruction Write
void LCD_DAT_Write(unsigned char pass_value); // Data Write
void LCD_putbyte(uchar c); // One Char Write to LCD
unsigned char LCD_DAT_Read(void); // lcd check if apear then = LCD_FLAG
void LCD_init(void);
void LCD_busy(void); // busy check
void delay(unsigned int number);
//application
/****************************************/
/* variables declarations */
/****************************************/
uchar flag;
/****************************************/
/* main function */
/****************************************/
void main(void){
EA=0; // Disable Interrupt
init_qbuffer(); // q-buffer setup
init_serial(); // 19200Bps setting
EA=1;
init_8255();
//******** lcd init setup********//
check_chip(); // check instrument, temp_init();
LCD_init();
LCD_clr(); // clear display DATA=0000 0001
//***** lcd init setup**************//
while(2000){
// for RS232 input
if(check_pop()){ // CR(Enter) check
// LCD_putbyte(xtoa_h(get_char)); // One Char Write to LCD
// LCD_putbyte(xtoa_l(get_char)); // One Char Write to LCD
switch(get_char){
/*
case(0x0D):
putstring("\nCMD>"); // check q-buffer and run
break;
case('h'):case('H'):case('?'):
putstring("This is Test Program Help \n Home page1(1), Tech_Support(2), This Massage Display(H)\nCMD>");
break;
case('u'):case('U'):
putstring("Thanks you~ uPMTEK.inc\nCMD>");
break;
*/
case('1'):case('!'): // step m/t front
LCD_goxy(1,1); // new 2 line 1 char
LCD_string(" ");// clear lcd
delay(10000);
LCD_goxy(1,1); // new 1 line 1 char
LCD_string("step Front !!");
front();
putbyte('1');
break;
case('2'):case('@'): // step m/t stop
LCD_goxy(1,1); // new 2 line 1 char
LCD_string(" ");// clear lcd
delay(10000);
LCD_goxy(1,1); // new 1 line 1 char
LCD_string("step Back !!");
back();
putbyte('2');
break;// end case('2')
case('3'):case('#'): // step m/t right
LCD_goxy(1,1); // new 2 line 1 char
LCD_string(" ");// clear lcd
delay(10000);
LCD_goxy(1,1); // new 1 line 1 char
LCD_string("step Right !!");
right();
putbyte('3');
break;
case('4'):case('$'): // step m/t left
LCD_goxy(1,1); // new 2 line 1 char
LCD_string(" ");// clear lcd
delay(10000);
LCD_goxy(1,1); // new 1 line 1 char
LCD_string("step Left !!");
left();
putbyte('4');
break;// end case('2')
case('5'):case('
putbyte('5');
break;
case('6'):case('^'): // step m/t right front
rf();
putbyte('6');
break;// end case('2')
case('7'):case('&'): // step m/t left back
lb();
putbyte('7');
break;
case('8'):case('*'): // step m/t right back
rb();
putbyte('8');
break;// end case('2')
case('9'):case('('): // step m/t right back
stepauto();
putbyte('9');
break;// end case('2')
case('R'):case('r'): // step m/t right back
autoright();
putbyte('R');
break;// end case('2')
case('L'):case('l'): // step m/t right back
autoleft();
putbyte('L');
break;// end case('2')
default: break;
} // end switch(get_char)
// get_char=NULL;
}// end if
} // end while(2000)
}// end main
// ========================================================
// ======================== Utility routine ===============
// ========================================================
bit check_pop(void){
if(q.wp!=q.rp){
get_char=(q.buffer[q.rp]); // pop get char by check flag
q.rp++; // Increment Read Point
if(q.rp>QSIZE) q.rp=0; // Read 번지증가
return (1);
}
get_char=NULL; // 입력이 없으면 공(空) 문자
return (0);
}
// ========================================================
// ======================== LCD ===============
// ========================================================
// ========================================================
// ======================== Initial routine ===============
// ========================================================
void init_qbuffer(void){ // 링 버퍼 초기화 루틴
q.rp=0; // Read point value = 0
q.wp=0; // write point value = 0
}
void init_serial(void){ // 19200
ES=1; // Enable Serial Interrupt
PS=1; // Serial Port Priority High
SCON = 0x50; // Mode=1, REN=1
PCON |= 0x80; // SMOD=1
TMOD |= 0x20; // Timer Mode=2, 8 Bit Auto_reload Timer
// TH1 = 0xFC; // 252=0xFC, Time Value, at 14.7456Mhz
TH1 = 253; // 253 Time Value, at 11.0592Mhz
TR1 = 1; // Run Timer 1
TI = 0;
RI = 0; // initial TI & RI
}
//====================================
//======== util_lib
//=============================
void putbyte(uchar c){ // TI=1이 될 때까지 실행한다.
SBUF = c;
while(!TI); // 괄호가 참이면 계속 실행, 즉 TI=0이면 대기
TI=0;
}
void putstring(char *str){ // Point 문자열 출력
unsigned int i;
for(i=0;str[i]!='\0';i++) {
if(str[i]=='\n') {
putbyte(0x0d); // 0x0d = Carriage Return(커서를 좌측 끝)
putbyte(0x0a); // 0x0a = Line Feed(줄 바꿈)
}
else putbyte(str[i]);
}
}
// ========================================================
// ======================== Interrupt ===============
// ========================================================
void push_q(void) interrupt 4 { // UART 인터럽트
if(RI){ // RI=1일 때 실행
RI=0; // Empty RI(다음 인터럽트 받을 준비)
q.buffer[q.wp]=SBUF; // Write Point로 옮김
q.wp++; // Increment Write point
if(q.wp>QSIZE) q.wp=0; // Write Point가 넘치지 않게(Ring Buffer)
} // End if(RI)
}
//======================================================
//================== Application ====================
//======================================================
void init_8255()
{
//XBYTE [CR] = CW ;
PPI_CR = CW;
delay(500);
}
void front() /* 전진 */
{
for(a = 0; a < 20; a++)
{
for(b = 0; b <= 3; b++)
{
PPI_A=st[b];
PPI_B=st[b];
delay(500);
}
}
}
void back()/* 후진 */
{
for(c=0; c<20; c++)
{
for(d = 3; d >= 0; d--)
{
PPI_A=st[d];
PPI_B=st[d];
delay(500);
}
}
}
void right()
{
for(a = 0; a < 40; a++)
{
for(b = 0; b <= 3; b++)
{
PPI_B=st[b];
delay(500);
}
}
}
void left()
{
for(a = 0; a < 40; a++)
{
for(b = 0; b <= 3; b++)
{
PPI_A=st[b];
delay(500);
}
}
}
void rf()
{
for(a = 0; a < 20; a++)
{
for(b = 0; b <= 3; b++)
{
PPI_B=st[b];
delay(500);
}
}
}
void lf()
{
for(a = 0; a < 20; a++)
{
for(b = 0; b <= 3; b++)
{
PPI_A=st[b];
delay(500);
}
}
}
void lb()
{
for(c=0; c<20; c++)
{
for(d = 3; d >= 0; d--)
{
PPI_A=st[d];
//PPI_B=st[d];
delay(500);
}
}
}
void rb()
{
for(c=0; c<20; c++)
{
for(d = 3; d >= 0; d--)
{
//PPI_A=st[d];
PPI_B=st[d];
delay(500);
}
}
}
void stepauto()
{
front();
back();
right();
back();
front();
back();
}
void autoright()
{
right();
right();
right();
right();
right();
}
void autoleft()
{
left();
left();
left();
left();
left();
}
void stop()
{
PPI_A=0x0f;
delay(2000);
}
void delay (uint i){ //지연함수
unsigned int j;
for(j=0;j<i;j++);
}
// ========================================================
// ======================== LCD ===============
// ========================================================
void LCD_string(uchar *s){ // string print to LCD
uchar i;
if(flag&LCD_FLAG){
for(i=0;s[i]!='\0';i++){
LCD_DAT_Write(s[i]); // Data Write
}
}
}
void LCD_goxy(unsigned char x, unsigned char y){// location
unsigned char pass;
if(flag & LCD_FLAG){
LCD_busy();
switch(y){
case(1): // 1 Line
pass=0x7F + x; // first line is 80h
LCD_CMD_Write(pass); // instruction Write
break;
case(2): // 2 Line
pass=0xBF + x; // C0h
LCD_CMD_Write(pass); // instruction Write
break;
case(3): // 3 line
pass=0x93 + x; // 94h
LCD_CMD_Write(pass); // instruction Write
break;
case(4): // 4 Line
pass=0xD3 + x; // D4h
LCD_CMD_Write(pass); // instruction Write
break;
}// end switch(y)
}// end if
}
void LCD_clr(void){ // clear display DATA=0000 0001
if(flag&LCD_FLAG){
LCD_busy();
LCD_CMD_Write(LCD_CLEAR);
LCD_goxy(1,1); // 1 line, 1 line
}
}
void LCD_CMD_Write(unsigned char pass_value){ // instruction Write
if(flag&LCD_FLAG){
LCDCOMD=pass_value; // 0x38;
LCD_busy(); // Busy bit Check
}
}
void LCD_putbyte(uchar c){ // One Char Write to LCD
if(flag&LCD_FLAG){
LCD_DAT_Write(c); // Data Write
}
}
void LCD_DAT_Write(unsigned char pass_value){ // Data Write
if(flag&LCD_FLAG){
LCDDATA_W=pass_value; // 0x38;
LCD_busy(); // Busy bit Check
}
}
unsigned char LCD_DAT_Read(void){ // lcd check if apear then = LCD_FLAG
unsigned char pass;
if(flag&LCD_FLAG){
pass=LCDDATA_R;
pass=LCDDATA_R;
pass=LCDDATA_R;// LCD_RS=1; LCD_RW=0;
return(pass);
}
}
void LCD_init(void){
unsigned char pass;
if(flag&LCD_FLAG){
pass=0x38;
LCDCOMD=pass; // 0x38; '1
delay(1); // Delay
LCDCOMD=pass; // 0x38; '2
delay(1); // Delay
LCDCOMD=pass; // 0x38; '3
delay(1); // Delay
// Function set D5=1, 001X XXXX System Set
// Data length(DL) D4=1, 0011 XXXX 8 Bit
// 1/16 duty-Bias D3=1, 001X 1XXX 16*2 line
// Character Font D2=0, 001X X0XX 5x7 Dot
// Total Data Value is 0011 10** 0x38
pass=0x0C; //
LCD_CMD_Write(pass); // 0000 1100 Display ON/OFF Control
// Display On/Off D3=1, 0000 1XXX System Set
// Entire Display(D) D2=1, 0000 11XX Display On
// Cursor On/Off(C) D3=0, 0000 1X0X Cusor Off
// Blinking(B) D2=0, 0000 1XX0 Blinking Off
// Total Data Value is 0000 1100 0x0C
LCD_CMD_Write(LCD_CLEAR); // 0000 0001 Clear Display
// Clear Display D0=1, 0000 0001 System Set
// Total Data Value is 0000 0001 0x01
pass=0x06; // Entry Mode set
LCD_CMD_Write(pass); // 0000 0110
// Entry Mode set D2=1, 0000 01XX System Set
// In/Decrement(I/D) D1=1, 0000 011X Increment
// Accompanies Dis(S)D0=0, 0000 01X0 Accompanies Display Shift Off
// Total Data Value is 0000 0110 0x06
}
}
void LCD_busy(void){ // busy check
unsigned char pass;
if(flag&LCD_FLAG){
do {
pass=LCDBUSY; // RS Pin=0 RW Pin=1
//Timer0_Delay(1); // Delay
}while(pass & LCD_BUSY); // LCD_BUSY=1000 0000
// 80(1000 0000)과 저장된 d 변수 값과 AND를 취한다.
// AND 결과가 참이면(Zero가 아니면) do로 되돌아감
// AND 결과가 거짓이면 (Zero이면) 루프를 빠져나감
}
}
// ========================================================
// ======================== Initial routine ===============
// ========================================================
void check_chip(void){
flag=0x0; // initial flag
if(LCD_DAT_Read()!=0xFF)flag|=LCD_FLAG; // LCD check ON
}
//====================================
//======== util_lib
//=============================
uchar xtoa_h(uchar _byteh){ // 16진수를 ASCII로 변환 상위 Nibble
uchar nibble = _byteh >> 4;
return ((nibble > 9)? nibble + 'A' - 10 : nibble + '0');
}
uchar xtoa_l(uchar _bytel){ // 16진수를 ASCII로 변환 하위 Nibble
uchar nibble = _bytel & 0x0F;
return ((nibble > 9)? nibble + 'A' - 10 : nibble + '0');
}
//void delay(unsigned int number){
//for(i=0;i<number;i++);
//}
|