📄 project.c
字号:
#include <io8535.h>
#include <macros.h>
// DataFlash chip select port pin (PB 4)
#define DF_CHIP_SELECT 0x10
//DataFlash opcodes
#define BUFFER_1_WRITE 0x84
#define BUFFER_2_WRITE 0x87
#define BUFFER_1_READ 0x54
#define BUFFER_2_READ 0x56
#define B1_TO_MM_PAGE_PROG_WITHOUT_ERASE 0x88
#define B2_TO_MM_PAGE_PROG_WITHOUT_ERASE 0x89
#define MM_PAGE_TO_B1_XFER 0x53
#define MM_PAGE_TO_B2_XFER 0x55
#define STATUS_REGISTER 0x57
#define BLOCK_ERASE 0x50
//These lines associate function names with interrupt handlers
#pragma interrupt_handler Timer0_int:IT_TIMER0_OVF0
#pragma interrupt_handler Timer2_int:IT_TIMER2_OVF2
#pragma interrupt_handler ADC_int:IT_ADC
//Utility macro to write to SPI and wait for the transfer to complete.
#define WRITE_SPI(x) SPDR = ((char)(x)); while (!(SPSR & temp));
//Global Variables
unsigned char sync; //Synchronization word. The timer sets this each time
//it is triggered, the rest of the software must wait
//for it to become '1', reset it to '0' and perform
//a task.
unsigned int adc_value; //The last read sample is stored here.
unsigned char led_state; //Stores the state of any blinking LEDs.
unsigned int buffer_max; //The max. size of the buffer (in bytes)
unsigned char reset_rec; //Resets the record position to a page boundary.
unsigned char lock;
unsigned int min_val = 0xFF;
/*
unsigned const char mu_table [512] = {
0, 3, 6, 9, 12, 14, 17, 19, 21, 23,
24, 26, 28, 29, 31, 32, 33, 34, 36, 37,
38, 39, 40, 41, 42, 43, 44, 45, 46, 46,
47, 48, 49, 50, 50, 51, 52, 52, 53, 54,
54, 55, 56, 56, 57, 57, 58, 59, 59, 60,
60, 61, 61, 62, 62, 63, 63, 64, 64, 65,
65, 66, 66, 66, 67, 67, 68, 68, 69, 69,
69, 70, 70, 70, 71, 71, 72, 72, 72, 73,
73, 73, 74, 74, 74, 75, 75, 75, 76, 76,
76, 77, 77, 77, 78, 78, 78, 78, 79, 79,
79, 80, 80, 80, 80, 81, 81, 81, 81, 82,
82, 82, 83, 83, 83, 83, 84, 84, 84, 84,
85, 85, 85, 85, 85, 86, 86, 86, 86, 87,
87, 87, 87, 87, 88, 88, 88, 88, 89, 89,
89, 89, 89, 90, 90, 90, 90, 90, 91, 91,
91, 91, 91, 92, 92, 92, 92, 92, 92, 93,
93, 93, 93, 93, 94, 94, 94, 94, 94, 94,
95, 95, 95, 95, 95, 95, 96, 96, 96, 96,
96, 96, 97, 97, 97, 97, 97, 97, 98, 98,
98, 98, 98, 98, 99, 99, 99, 99, 99, 99,
99, 100, 100, 100, 100, 100, 100, 100, 101, 101,
101, 101, 101, 101, 101, 102, 102, 102, 102, 102,
102, 102, 102, 103, 103, 103, 103, 103, 103, 103,
104, 104, 104, 104, 104, 104, 104, 104, 105, 105,
105, 105, 105, 105, 105, 105, 106, 106, 106, 106,
106, 106, 106, 106, 106, 107, 107, 107, 107, 107,
107, 107, 107, 108, 108, 108, 108, 108, 108, 108,
108, 108, 109, 109, 109, 109, 109, 109, 109, 109,
109, 109, 110, 110, 110, 110, 110, 110, 110, 110,
110, 111, 111, 111, 111, 111, 111, 111, 111, 111,
111, 112, 112, 112, 112, 112, 112, 112, 112, 112,
112, 113, 113, 113, 113, 113, 113, 113, 113, 113,
113, 113, 114, 114, 114, 114, 114, 114, 114, 114,
114, 114, 114, 115, 115, 115, 115, 115, 115, 115,
115, 115, 115, 115, 116, 116, 116, 116, 116, 116,
116, 116, 116, 116, 116, 116, 117, 117, 117, 117,
117, 117, 117, 117, 117, 117, 117, 117, 118, 118,
118, 118, 118, 118, 118, 118, 118, 118, 118, 118,
119, 119, 119, 119, 119, 119, 119, 119, 119, 119,
119, 119, 119, 120, 120, 120, 120, 120, 120, 120,
120, 120, 120, 120, 120, 120, 121, 121, 121, 121,
121, 121, 121, 121, 121, 121, 121, 121, 121, 121,
122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
122, 122, 122, 122, 123, 123, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 123, 123, 123, 124,
124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
124, 124, 124, 124, 125, 125, 125, 125, 125, 125,
125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
126, 126, 126, 126, 126, 126, 127, 127, 127, 127,
127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127 };
unsigned const char mu_table [512] = {
0, 1, 2, 4, 5, 6, 7, 8, 10, 11,
12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
21, 22, 23, 24, 25, 26, 26, 27, 28, 29,
29, 30, 31, 32, 32, 33, 34, 34, 35, 36,
36, 37, 37, 38, 39, 39, 40, 40, 41, 41,
42, 43, 43, 44, 44, 45, 45, 46, 46, 47,
47, 48, 48, 49, 49, 50, 50, 51, 51, 51,
52, 52, 53, 53, 54, 54, 54, 55, 55, 56,
56, 56, 57, 57, 58, 58, 58, 59, 59, 60,
60, 60, 61, 61, 61, 62, 62, 62, 63, 63,
64, 64, 64, 65, 65, 65, 66, 66, 66, 67,
67, 67, 67, 68, 68, 68, 69, 69, 69, 70,
70, 70, 70, 71, 71, 71, 72, 72, 72, 72,
73, 73, 73, 74, 74, 74, 74, 75, 75, 75,
75, 76, 76, 76, 77, 77, 77, 77, 78, 78,
78, 78, 79, 79, 79, 79, 79, 80, 80, 80,
80, 81, 81, 81, 81, 82, 82, 82, 82, 83,
83, 83, 83, 83, 84, 84, 84, 84, 84, 85,
85, 85, 85, 86, 86, 86, 86, 86, 87, 87,
87, 87, 87, 88, 88, 88, 88, 88, 89, 89,
89, 89, 89, 90, 90, 90, 90, 90, 91, 91,
91, 91, 91, 91, 92, 92, 92, 92, 92, 93,
93, 93, 93, 93, 93, 94, 94, 94, 94, 94,
94, 95, 95, 95, 95, 95, 96, 96, 96, 96,
96, 96, 97, 97, 97, 97, 97, 97, 97, 98,
98, 98, 98, 98, 98, 99, 99, 99, 99, 99,
99, 100, 100, 100, 100, 100, 100, 100, 101, 101,
101, 101, 101, 101, 102, 102, 102, 102, 102, 102,
102, 103, 103, 103, 103, 103, 103, 103, 104, 104,
104, 104, 104, 104, 104, 105, 105, 105, 105, 105,
105, 105, 105, 106, 106, 106, 106, 106, 106, 106,
107, 107, 107, 107, 107, 107, 107, 107, 108, 108,
108, 108, 108, 108, 108, 108, 109, 109, 109, 109,
109, 109, 109, 109, 110, 110, 110, 110, 110, 110,
110, 110, 111, 111, 111, 111, 111, 111, 111, 111,
112, 112, 112, 112, 112, 112, 112, 112, 112, 113,
113, 113, 113, 113, 113, 113, 113, 113, 114, 114,
114, 114, 114, 114, 114, 114, 115, 115, 115, 115,
115, 115, 115, 115, 115, 115, 116, 116, 116, 116,
116, 116, 116, 116, 116, 117, 117, 117, 117, 117,
117, 117, 117, 117, 118, 118, 118, 118, 118, 118,
118, 118, 118, 118, 119, 119, 119, 119, 119, 119,
119, 119, 119, 119, 120, 120, 120, 120, 120, 120,
120, 120, 120, 120, 121, 121, 121, 121, 121, 121,
121, 121, 121, 121, 121, 122, 122, 122, 122, 122,
122, 122, 122, 122, 122, 122, 123, 123, 123, 123,
123, 123, 123, 123, 123, 123, 124, 124, 124, 124,
124, 124, 124, 124, 124, 124, 124, 124, 125, 125,
125, 125, 125, 125, 125, 125, 125, 125, 125, 126,
126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
126, 127, 127, 127, 127, 127, 127, 127, 127, 127,
127, 127 };
*/
//This function sets up port directions. Does not touch other peripherals.
void setup () {
DDRB = 0xBD; //PortB Direction
/*
76543210
1....... = SCK (Output)
.0...... = MISO (Input)
..1..... = MOSI (Output)
...1.... = CS (Output)
....x... = Unused (Output)
.....1.. = WP (Output)
......0. = RDYBSY (Input)
.......1 = RST (Output)
11011011 = 0xBD
*/
PORTB = 0xFF; //Make all o/p high, all i/p have pullups
DDRA = 0x00; //PortA is entirely input (shared with ADC)
PORTA = 0x00; //Remove pullups from PORTA
DDRD = 0x10; //PortD is all-input, except Bit 4
//Bits 0 to 3 are all inputs from switches,
//Bit 4 is the PWM output.
PORTD = 0xFF; //All switches have pullups.
DDRC = 0x0F; //Bits 0 to 3 of PortC are outputs (to LEDs), bits
//4 to 7 are unused, and left as inputs.
_SEI(); //Enable global interrupts.
}
//Initialize ADC and make it perform a conversion.
void init_ADC (void) {
ADCSR = 0x00; //disable adc
//ADMUX = 0x00; //select adc input 0, in DIP version
ADMUX = 0x03; //select adc input 3, in PLCC version
ADCSR = 0xCA; //Enable ADC, make it perform a conversion, Enable
//ADC interrupt, sample interval prescaler set to /2
}
//Called at the sampling rate (8000Hz)
void Timer0_int (void) {
TCNT0 = 0x83; //Set the counter reg to get a sampling rate of 8000Hz
sync = 1; //Set the synchronization flag
}
//Called to blink LEDs
void Timer2_int (void) {
static char ctr;
ctr++;
if (ctr > 7) { //Blink two times per second.
ctr = 0;
//if any bits in led_state are high, invert the state of that LED
if (led_state & 0x01) PORTC ^= 0x01;
if (led_state & 0x02) PORTC ^= 0x02;
if (led_state & 0x04) PORTC ^= 0x04;
if (led_state & 0x08) PORTC ^= 0x08;
}
}
//Called when the ADC finishes a conversion.
void ADC_int (void) {
adc_value = ADCL; //Read 8 low bits first (important)
adc_value |= (int)ADCH << 8; //read 2 high bits and shift into top byte
}
//Enables Timer1 as a PWM generator, with 8-bit input and carrier generation
//at 15686 Hz.
void enable_PWM () {
TCCR1A = 0x21; //Set Timer1 to PWM Mode, output on OC1B,
//non-inverting 8-bit PWM
TCNT1 = 0x00; //Initialize counter to 0;
TIFR = 0x04; //Clear all Timer Interrupts
TCCR1B = 0x01; //Enable timer with prescaler set to 1
OCR1B = 0x00; //Initial PWM value
}
//Enables Timer0 as a sampling period timer (8000Hz).
void enable_timer0 () {
TCCR0 = 0x02; //Enable Timer0 with prescaler set to /8
TIMSK |= 0x01; //Enable Timer0 interrupt in mask register
}
//Writes the previous buffer (filled with data from the ADC) to the main
//memory array of the DataFlash
void prev_page_to_prev_buffer (unsigned char active_buffer,
unsigned int page_counter) {
unsigned char temp = 0x80;
//while (!(PINB & 0x02)); //Wait till flash is ready
PORTB &= ~DF_CHIP_SELECT; //Enable Flash
if (active_buffer == 1) { //Transfer inactive buffer to page
WRITE_SPI (B2_TO_MM_PAGE_PROG_WITHOUT_ERASE);
}
else {
WRITE_SPI (B1_TO_MM_PAGE_PROG_WITHOUT_ERASE);
}
if (buffer_max == 528) {
WRITE_SPI (page_counter >> 6); //Write first part of page counter
WRITE_SPI (page_counter << 2); //Write next part of page counter
}
else {
WRITE_SPI (page_counter >> 7); //Write first part of page counter
WRITE_SPI (page_counter << 1); //Write next part of page counter
}
WRITE_SPI (0x00); //Dont care bits
PORTB |= DF_CHIP_SELECT; //Disable the DataFlash
}
void adc_to_active_buffer (unsigned char active_buffer) {
unsigned int buffer_counter = 0, t;
unsigned char temp = 0x80;
PORTB &= ~DF_CHIP_SELECT; //Enable Flash
if (active_buffer == 1) { //Transfer data to active buffer
WRITE_SPI (BUFFER_1_WRITE); //Command to read buffer 1
}
else {
WRITE_SPI (BUFFER_2_WRITE); //Command to read buffer 2
}
WRITE_SPI (0x00); //Dont care bits
WRITE_SPI (0x00); //Dont care bits
WRITE_SPI (0x00); //Dont care bits
WRITE_SPI (0x00); //Dont care bits
while (buffer_counter < buffer_max) { //As long as buffer is not done...
while (!sync); //Wait for synchronization
sync = 0; //Clear the sync.
//Write the last ADC value.
if (adc_value < min_val) min_val = adc_value;
t = (adc_value - min_val) >> 1;
if (t < 256) {
WRITE_SPI (t);
}
else {
WRITE_SPI (255);
if (min_val) min_val--;
}
//WRITE_SPI (((t < 256) ? t : 255));
/*
t = mu_table [abs(adc_value - 533)];
if (adc_value < 533) t = 128 - t;
else t += 128;
WRITE_SPI (t);
*/
ADCSR = 0xC9; //Start a new conversion
buffer_counter++; //increment buffer pos.
}
min_val++;
PORTB |= DF_CHIP_SELECT; //Disable the DataFlash
}
//Instructs the DataFlash to transfer the contents of a specified page into
//the inactive buffer. This happens without CPU intervention, and in parallel
//with the retrieval of samples from the active buffer.
void next_page_to_next_buffer (unsigned char active_buffer,
unsigned int page_counter) {
unsigned char temp = 0x80;
while (!(PINB & 0x02)); //Wait till flash is ready
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -