📄 pyzc4.c
字号:
//#pragma model(196)
#include <80c196kd.h>
#define SP_MODE0 0x00
#define SP_MODE1 0x01
#define SP_MODE2 0x02
#define SP_MODE3 0x03
#define REC_ENABLE 0x08
#define REC_DISABLE 0x00
#define TXD_ENABLE_BIT 0x05
#define EVEN_PARITY 0x08
#define ODD_PARITY 0x28
#define NO_PARITY 0x00
#define SET_BIT_8 0x04
#define SP_INTERNAL_CLK 0x8000
#define SP_EXTERNAL_CLK 0x0000
#define TXD_INTERRUPT 0x00
#define RXD_INTERRUPT 0x01
//#define SERIAL_INT 0x06
#define TI_BIT 0x05
#define RI_BIT 0x06
#define FE_BIT 0x04
#define OE_BIT 0x02
#define RPE_BIT 0x07
#define RB8_BIT 0x07
#define TXE_BIT 0x03
#define T1OVF_DETECTION 2
#define TOVF_INT_MSK 0
#define T2OVF_INT_MSK 4
#define T2CAPTURE_INT_MSK 3
#define T2OVF_DETECTION 3
#define T2_CLOCK_INTERNAL 0
#define TOVF_INT 0
#define AD_INT 1
#define HSI_DATA_AVAIL_INT 2
#define HSO_INT 3
#define HSI0_INT 4
#define SW_TIMER_INT 5
#define SERIAL_INT 6
#define EXT_INT 7
#define TRAP_INT 8
#define UNIMPLEMENTED_INT 9
#define TXD_INT 24
#define RXD_INT 25
#define HSI_FIFO4_INT 26
#define TIMER2_CAPT_INT 27
#define T2OVF_INT 28
#define EXT1_INT 29
#define HSI_FIFO_FULL_INT 30
#define NONMASKABLE_INT 31
#define PWM0_ENABLE 0
#define PWM_PRESCALE 2
#define HSO4_PIN_ENABLE 4
#define HSO5_PIN_ENABLE 6
#define CAM_LOCK_BIT 6
#define CLEAR_CAM_BIT 7
#define ATOD_BUSY (ad_result & 0x08)
#define GO_NOW 0x08
#define GO_EPA 0x00
#define TEN_BIT_MODE 0x00
#define EIGHT_BIT_MODE 0x10
#define AD_SPEED 4
#define AD_INT 1
#define HSI0_PIN_ENABLE 0
#define HSI0_EXT_INT 0x10
#define HSI1_PIN_ENABLE 2
#define HSI2_PIN_ENABLE 4
#define HSI3_PIN_ENABLE 6
#define SELECT_INT_VECTOR 7
#define HSI_FIFO_FULL_INTMSK 0x40
#define HSI_FIFO_4_INT 0x4
#define EXTINT_SRC 1
/****************************************************************************/
/* */
/* Usefull bit macros. */
/* */
/****************************************************************************/
#define checkbit(var,bit) (var & (0x01 << (bit)))
#define setbit(var,bit) (var |= (0x01 << (bit)))
#define clrbit(var,bit) (var &= (~(0x01 << (bit))))
static unsigned char sp_status_image;
register unsigned int tmpreg;
#pragma interrupt(serial_isr=6)
#pragma interrupt (tovf_isr = TOVF_INT)
#pragma interrupt (ext_isr = EXT_INT)
#pragma interrupt (hsi0_isr = HSI0_INT)
const unsigned int ccr = {0x20CD};
#pragma locate(ccr=0x2018)
#define TRANSMIT_BUF_SIZE 20
#define RECEIVE_BUF_SIZE 20
static unsigned char trans_buff[TRANSMIT_BUF_SIZE];
static unsigned char mess[12]={'S',0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,'E'};
static char begin_trans_buff,end_trans_buff;
static unsigned char receive_buff[RECEIVE_BUF_SIZE];
static char end_rec_buff,begin_rec_buff;
static unsigned char pwm0_byte,ioport1_byte,hso_byte,pulse=0;
static unsigned char timer1_count=0,triggle_out=0,triggle_in=0,emergence_flag=0;
extern void enable(void);
void ext_isr(void)
{
/* User code goes here */
emergence_flag=1;
}
void hsi0_isr(void)
{
/* User code goes here */
unsigned char temp_byte;
unsigned int temp_word;
pulse++;
temp_byte=hsi_status;
temp_word=hsi_time;
}
void tovf_isr(void)
{
/* User code goes here */
if(++timer1_count==12)
{
triggle_out=1;
timer1_count=0;
mess[8]=pulse;
if(emergence_flag==1)
{
emergence_flag=0;
mess[8]|=0x80;
}
pulse=0;
}
}
void transmit(void) /* serial interrupt routine */
{
sp_status_image |= sp_stat; /* image sp_stat into
sp_status_image */
/* transmit a character if there is a character in the buffer
else leave TI_BIT set in image for putchar to enable interrupts */
if(begin_trans_buff!=end_trans_buff)
{
sbuf=trans_buff[begin_trans_buff]; /* transmit character */
/* The next statement makes the buffer circular by starting over when the
index reaches the end of the buffer. */
if(++begin_trans_buff>TRANSMIT_BUF_SIZE - 1)begin_trans_buff=0;
clrbit(sp_status_image,TI_BIT); /* clear TI bit in status_image. */
}
}
int putchar(int c)
{
/* remain in loop while the buffer is full. This is done by checking
the end of buffer index to make sure it does not overrun the
beginning of buffer index. The while instruction checks the case
when the end index is one less then the beginning index and at the
end of the buffer when the beginning index may be equal to 0 and
the end buffer index may be at the buffer end. */
while((end_trans_buff+1==begin_trans_buff)||
(end_trans_buff==TRANSMIT_BUF_SIZE -1 && !begin_trans_buff));
trans_buff[end_trans_buff]=c; /* put character in buffer */
if(++end_trans_buff>TRANSMIT_BUF_SIZE - 1) /* make buffer appear */
end_trans_buff=0; /* circular. */
if(checkbit(sp_status_image, TI_BIT))
{
setbit(int_pend, SERIAL_INT); /* If transmit buffer
was empty, then cause
an interrupt to start
transmitting. */
}
}
unsigned char getchar()
{
while(begin_rec_buff==end_rec_buff); /* remain in loop while there is
not a character avaliable. */
if(++begin_rec_buff>RECEIVE_BUF_SIZE - 1) /* make buffer appear */
begin_rec_buff=0; /* circular. */
return(receive_buff[begin_rec_buff]); /* return the character in
buffer. */
}
void receive(void) /* serial interrupt routine */
{
unsigned char c;
sp_status_image |= sp_stat; /* image sp_stat into status_image */
/* If the input buffer is full, the last character can be handled
as desired. */
if(end_rec_buff+1==begin_rec_buff || (end_rec_buff==RECEIVE_BUF_SIZE-1 &&
!begin_rec_buff))
{
; /* input overrun code */
}
else
{
/* The next statement makes the buffer circular by starting over when the
index reaches the end of the buffer. */
if(++end_rec_buff > RECEIVE_BUF_SIZE - 1) end_rec_buff=0;
receive_buff[end_rec_buff]=sbuf; /* place character in
buffer */
if(receive_buff[end_rec_buff]==0x45 && receive_buff[(end_rec_buff+RECEIVE_BUF_SIZE-1)%RECEIVE_BUF_SIZE]==0x00 && receive_buff[(end_rec_buff+RECEIVE_BUF_SIZE-5)%RECEIVE_BUF_SIZE]==0x53)
{
triggle_in=1;
++mess[9];
pwm0_byte=receive_buff[(end_rec_buff+RECEIVE_BUF_SIZE-4)%RECEIVE_BUF_SIZE];
ioport1_byte=receive_buff[(end_rec_buff+RECEIVE_BUF_SIZE-3)%RECEIVE_BUF_SIZE];
hso_byte=receive_buff[(end_rec_buff+RECEIVE_BUF_SIZE-2)%RECEIVE_BUF_SIZE];
}
c=getchar(); //Discard a char,since now deal it in serial_in_interrupt.
if(checkbit(sp_status_image, FE_BIT))
{
; /* User code for framing error */
clrbit(sp_status_image, FE_BIT);
}
if(checkbit(sp_status_image, OE_BIT))
{
; /* User code for overrun error */
clrbit(sp_status_image, OE_BIT);
}
}
clrbit(sp_status_image,RI_BIT); /* clear RI bit in status_image. */
}
/* The seperate txd and rxd interrupts can more efficiently process
the interrupts than the generic serial interrupt as this one
does.
*/
void serial_isr(void)
{
sp_status_image |= sp_stat; /* image sp_stat into status_image */
if(checkbit(sp_status_image, RI_BIT))
receive();
else if(checkbit(sp_status_image, TI_BIT))
transmit();
}
void init_serial()
{
/*
* Serial port configuration:
* serial mode = 1
* even parity = disabled
* serial receive = enabled
* serial transmit = enabled
*/
_SetSFR_bit (ioc1, TXD_ENABLE_BIT);
_WriteSFR (sp_con, 0x9);
/*
* Baud Rate = 0
*/
_WriteSFR (baud_rate, 0x70);
_WriteSFR (baud_rate, 0x82);
/*
* Interrupts:
* transmit interrupt = disabled
* receive interrupt = disabled
* serial interrupt = enabled
*/
_SetSFR_bit (int_mask, SERIAL_INT);
_ClrSFR_bit (int_mask1, TXD_INTERRUPT);
_ClrSFR_bit (int_mask1, RXD_INTERRUPT);
end_rec_buff=0; /* initialize buffer pointers */
begin_rec_buff=0;
end_trans_buff=0;
begin_trans_buff=0;
sp_status_image = 0x20; /* Init for initial transmittion */
}
void init_timer1(void)
{
/*
* Timer 1 configuration:
* overflow detection = enabled
*/
_SetSFR_bit (ioc1, T1OVF_DETECTION);
/*
* timer overflow interrupt = enabled
*/
_SetSFR_bit (int_mask, TOVF_INT_MSK);
}
void init_pwm0(void)
{
/*
* PWM0 configuration:
* prescaler mode = divide by 1
* PWM output = enabled
* PWM duty cycle = 50.00 %
*
* pwm0_control = 256 * (Duty Cycle) / 100
*/
_ClrSFR_bit (ioc2, PWM_PRESCALE);
_WriteSFR (pwm0_control, 0x80);
_SetSFR_bit (ioc1, PWM0_ENABLE);
}
void init_hso1_5(void)
{
/*
* HSO 5 module initialization:
* HSO5 output = enabled
* cam locking = disabled
* clear cam = no
*/
_SetSFR_bit (ioc1, HSO4_PIN_ENABLE);
_SetSFR_bit (ioc1, HSO5_PIN_ENABLE);
_ClrSFR_bit (ioc2, CAM_LOCK_BIT);
_ClrSFR_bit (ioc2, CLEAR_CAM_BIT);
/*
* Interrupts:
* HSO interrupt = disabled
* software timer int = disabled
*/
_ClrSFR_bit (int_mask, HSO_INT);
_ClrSFR_bit (int_mask, SW_TIMER_INT);
}
void init_atod_converter(void)
{
/*
* A/D conversion configuration:
* speed = normal
* interrupt = disabled
* channel = 0
* start time = started immediately
* mode = 10-bit
*/
_ClrSFR_bit (ioc2, AD_SPEED);
_ClrSFR_bit (int_mask, AD_INT);
_WriteSFR (ad_command, 0x8);
}
/* convert_atod performs an atod conversion and. This routine
waits until the atod busy bit is cleared before and after the
conversion. Interrupts should be disabled and the ATOD
should be initialized prior to calling this routine. */
unsigned int convert_atod(unsigned char channel)
{
wsr = 0;
while(ATOD_BUSY);
ad_command = channel | GO_NOW | TEN_BIT_MODE;
zero_reg=zero_reg+zero_reg; /* needed for 4 state delay */
zero_reg=zero_reg+zero_reg; /* needed for 4 state delay */
while(ATOD_BUSY);
return((ad_result >> 6));
}
void init_hsi0(void)
{
/*
* HSI 0 module configuration:
* input capture mode = each positive transition
* hsi 0 external pin = enabled
*/
_ClrSFR_bit (hsi_mode, 1);
_SetSFR_bit (hsi_mode, 0);
_SetSFR_bit (ioc0, HSI0_PIN_ENABLE);
/*
* Interrupts
* sixth fifo int vector = hsi data available
* hsi 0 pin interrupt = enabled
* hsi data available int = disabled
* hsi fifo full int = disabled
* hsi fifo 4 int = disabled
*/
_ClrSFR_bit (ioc1, SELECT_INT_VECTOR);
_ClrSFR_bit (int_mask, 2); /* hsi data available */
_SetSFR_bit (int_mask, 4); /* hsi0 external interrupt */
_AndSFR (int_mask1, ~(HSI_FIFO_FULL_INTMSK + HSI_FIFO_4_INT));
}
/*
* external interrupt source = extint pin
*/
void init_extint_src(void)
{
_ClrSFR_bit (ioc1, EXTINT_SRC);
}
void init_interrupts(void)
{
/*
* Timer overflow interrupt = disabled
* A/D conversion complete interrupt = disabled
* HSI data available interrupt = disabled
* HSO interrupt = disabled
* HSI.0 pin interrupt = enabled
* Timer interrupt = disabled
* Serial port interrupt = disabled
* External interrupt = enabled
* Transmit interrupt = disabled
* Receive interrupt = disabled
* HSI fifo 4 interrupt = disabled
* Timer 2 capture interrupt = disabled
* Timer 2 overflow interrupt = disabled
* External Interrupt 1 = disabled
* HSI fifo full interrupt = disabled
*/
_SetSFR_bit (int_mask, HSI0_INT);
_SetSFR_bit (int_mask, EXT_INT);
}
void main(void)
{
unsigned char i,chno=0;
unsigned int result,ad_result[2];
init_serial();
init_timer1();
init_pwm0();
init_hso1_5();
init_atod_converter();
init_hsi0();
init_extint_src();
init_interrupts();
enable();
/* The following line will loop until the letter 'Q' is
received. */
putchar('H');
putchar('e');
putchar('l');
putchar('l');
putchar('o');
//while(getchar() != 'Q')
while(1)
{
//result = convert_atod(0x00);
result = convert_atod(chno);
ad_result[chno]=result;
if(++chno==2) chno=0;
if(triggle_out==1)
{
triggle_out=0;
wsr=0;
wsr = 0x0;
mess[1]=ad_result[0]>>8;
mess[2]=ad_result[0];
mess[3]=ad_result[1]>>8;
mess[4]=ad_result[1];
mess[5]=ioport0;
mess[6]=ioport2;
mess[7]=hsi_status;
//mess[8]=pulse;
for(i=0;i<12;i++) putchar(mess[i]);
}
if(triggle_in==1)
{
triggle_in=0;
pwm0_control=pwm0_byte; //receive_buff[(end_rec_buff+RECEIVE_BUF_SIZE-4)%RECEIVE_BUF_SIZE];
ioport1=ioport1_byte; //receive_buff[(end_rec_buff+RECEIVE_BUF_SIZE-3)%RECEIVE_BUF_SIZE];
for(i=0;i<5;i++)
{
hso_command=((hso_byte & (1<<i))>>i)*0x20+i;
hso_time=20;
}
}
}
/* Example of sending out buffered data. */
//while(1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -