Prime-ary Prototype: Complete!
596 words | Posted by Scott on June 10th, 2009
Scott was 23.71 years old when he wrote this!
Filed under: C/C++, Circuitry, General, Microcontrollers, Prime Numbers
For the last several weeks I’ve been hacking together a small prototype of a microcontroller (ATTiny2313)-powered prime number generator. I can finally say that it (the prototype) is complete, functional, and elegant [get the song I'm referencing while it's up!]. The name says what it does, so I won’t waste time describing it. If you’re interested in how it does what it does, check out the other posts with the same category tag for a full (and I mean full as in “more than you ever wanted to know”) description. A schematic is soon to come. Code is below. For now, here’s a video of the completed project:
And the source code I used. I chose the ATTiny2313 because it was cheap (~$2) and has 18 IO pins to work with. I had to fight memory usage every step of the way. I’m limited to 2kb, and this program compiles within 1% of that! For future projects (more LEDs, more menus) I’ll use the 20-pin and/or 40-pin ATMega series. I’m thinking about having one be in charge of the display (multiplexing) leaving the other to think about generating prime numbers.
#define F_CPU 10240000
#include <avr/interrupt.h>
#include <util/delay.h>
#include <math.h>
// ~~~ PORT D ~~~
#define r1 0b00000100
#define r2 0b00000010
#define r3 0b00001000
#define r4 0b00100000
#define r5 0b00010000
#define f1 0b01000000
#define id 0b00000001
#define f0 0b10111111
// ~~~ PORT B ~~~
#define c1 0b00010000
#define c2 0b00000001
#define c3 0b00000010
#define c4 0b00000100
#define c5 0b00001000
char delay=1;
int redo=0;
char rows[] = {r1,r2,r3,r4,r5};
char cols[] = {c1,c2,c3,c4,c5};
char vals[] = {0,0,0,0,0};
char funcs=f1+id;
unsigned long showNum=5;//33554431;
void displayNum();
void incrimentNum();
void menu_pause();
void menuCheck();
char button();
char isPrime(unsigned long);
unsigned int twoTo(char);
int main(void) {
DDRD = r1+r2+r3+r4+r5+f1+id;
DDRB = c1+c2+c3+c4+c5;
DDRB &= ~_BV(DDB7);
PORTB = 0;
PORTD = 0;
unsigned int i=0;
int j;
//convertNum();
//showNum=5;
while (1) {
showNum+=1;
if (isPrime(showNum)){
convertNum();
}
for (j=0;j<redo;j++) {
displayNum();
menu();
}
if (i%10==0){funcs^=r1;
funcs^=id;
if (i%100==0){funcs^=r2;
if (i%1000==0){funcs^=r3;i=0;
}
}
}
i++;
}
return 0;
}
char isPrime(unsigned long test){
if (test%2==0) return 0;
unsigned long div = 3;
while(div*div<test+1){
if (test%div==0) return 0;
div+=2;
displayNum();
}
return 1;
}
void menu(){
//return;
char j,but;
but = button();
if (but==0) return;
else if (but==1){
while (1) {
PORTD=id;
if (PINB & _BV(PB7)) {
funcs=f1;
for (j=0;j<200;j++){
if (j%25==0) funcs^=r1;
displayNum();
}
}
else {
if (redo==0) redo=200;
else redo=0;
_delay_ms(300);
return;
}
}
}
return;
}
char button(){
PORTD=id;
if (PINB & _BV(PB7)) return 0; // not pressed
_delay_ms(1000);
if (PINB & _BV(PB7)) return 1; // pressed
return 2; // held down
}
void convertNum(){
char col,row,rowcode;
unsigned long msk=1;
for (col=0;col<5;col++){
rowcode=0;
for (row=0;row<5;row++){
if (showNum&msk) rowcode+=rows[row];
msk = msk < < 1;
}
vals[col]=rowcode;
}
return;
}
void displayNum(){
char i,j;
PORTB = 0b0;
PORTD = funcs;
_delay_ms(delay);
for (i=0;i<5;i++){
PORTD = vals[i];
PORTB = cols[i];
_delay_ms(delay);
}
return;
}
This entry was posted on Wednesday, June 10th, 2009 at 7:16 pmand is filed under C/C++, Circuitry, General, Microcontrollers, Prime Numbers. You can follow any responses to this entry through the RSS 2.0 feed. You can skip to the end and leave a response. Pinging is currently not allowed.